00:00:13.840
Hi! So, who among you has used Chef? Yay! My talk will make sense, so anyway.
00:00:20.080
I'm Marta Paciorkowska, a junior software engineer at CEO of Coins. You know the drill: Twitter, GitHub.
00:00:26.400
I'm here to talk about Chef Browser.
00:00:32.320
Chef Browser is a very simple tool designed to enhance your everyday work with Chef. If you use Chef, you probably also use Knife.
00:00:39.600
If you frequently use commands like `knife show` and `knife list`, you might have noticed that finding certain types of data can be cumbersome.
00:00:45.280
For example, when you realize how nested some of the JSON attributes are, it might not be so easy to make sense of them.
00:00:51.680
You may find yourself lost regarding your exact location within the data. Additionally, since it's a console tool, sometimes you may want a full-fledged app for that.
00:01:06.960
That's where Chef Browser comes in. It's a read-only Chef web UI, which I will showcase today.
00:01:12.240
Chef Browser is made in Ruby and Sinatra, and it is completely open source. If you like it, you can contribute to it.
00:01:19.759
Now, let me show you a live demo of how Chef Browser looks.
00:01:25.600
All I have to do is download it from GitHub, set it up, and Chef Browser allows you to secure access to your data via a login screen.
00:01:31.200
All users that have access to this data come from the Knife user list.
00:01:38.479
So, as a Knife user, I type in my super secret password and I'm in.
00:01:44.799
The first thing I see is a list of attributes, which includes all the resources available on my Chef server.
00:01:51.439
These are divided into environments, roles, and data bags. You can also view data bag items.
00:01:58.079
When I click on any of those nodes, environments, or roles, I can see all the attributes of a given resource.
00:02:04.640
The views of the attributes are specific to the resource, but the basics are the same. First, you see general information about the resource.
00:02:12.800
When it comes to nodes, you can see FQDN, IP addresses, the environment this node is running in, and all associated tags.
00:02:19.280
You can click on these tags and view the node's run list.
00:02:24.480
Below that, you can see a handy list of JSON attributes, which I present in a flat structure as a JSON path.
00:02:30.480
Regardless of how deeply nested you are, you know exactly where you are. Moreover, all the attributes are divided into different categories.
00:02:36.640
As you can see, they fall under default, normal, override, and automatic categories based on their priority.
00:02:44.640
This makes it very easy to navigate through the data.
00:02:52.480
For example, if you want to know what Ohai is responsible for, you just click on the automatic tab.
00:02:59.280
Another cool feature of Chef Browser is live filtering of all the attributes.
00:03:05.280
If you're unsure of what you're looking for, you can simply experiment by typing keywords.
00:03:13.440
For instance, if I type 'ruby', I can see everything that matches that term.
00:03:20.879
You can also search for nested data by adding a dot to your query, such as looking for versions.
00:03:26.879
And there you go!
00:03:31.920
Chef Browser also mimics a Knife search. For example, if I want to look for nodes named 'production' or 'batch', I can enter that in the search field.
00:03:38.720
Just press enter, and here are all the nodes named 'batch'.
00:03:43.840
If I search for specific information, for example, a person who keeps forgetting their MySQL password, I can simply open my settings file.
00:03:49.920
It’s a simple file that looks more or less like this.
00:03:55.760
In this file, I can define my saved searches.
00:04:02.160
Then, when I run Chef Browser, those saved searches will appear.
00:04:07.840
For instance, I can just click here, and voilà! There it is.
00:04:26.960
Environments look a little different. Besides a list of attributes, you can also easily find all the nodes connected to a specific environment.
00:04:34.479
This is very useful, especially for roles. You can see the run list on the role's dashboard.
00:04:41.240
Everything in the UI is clickable, allowing for easy navigation.
00:04:47.680
In the future, we are planning to implement support for handling cookbooks, so you'll be able to view recipes and the contents of every file in a cookbook.
00:05:26.960
Uh, Florian, are you still here?
00:05:42.080
Ready, set...
00:05:49.759
Ready, set, go! You're cheating! I'm cheating! Hi, Norbert!
00:05:55.600
I want to tell you about my favorite Ruby refactoring tool. We're going to pull some code off of GitHub.
00:06:01.759
But we're not going to analyze the code; instead, we are interested in code shape.
00:06:07.680
So, we have a class. Since it's a real project, it inherits from multiple other classes and has a method that does one thing.
00:06:14.960
It is a good method. However, as requirements evolve, we start incorporating branching.
00:06:20.560
Then there are assertions we need to do ahead of time.
00:06:26.400
We begin including other code that does things not necessarily related to that method.
00:06:32.800
This other code starts throwing exceptions, and it becomes overwhelming to handle all these errors.
00:06:39.520
Over time, these methods evolve into humongous beasts that we cannot effectively manage.
00:06:45.840
Eventually, someone suggests adding comments to help make sense of it all.
00:06:52.160
This may help momentarily, but the real solution is to revert that commit quickly.
00:06:57.199
Then we need to perform the next best thing, which is to extract the method.
00:07:03.840
It turns out that usually, when you extract, you create even more blocks, which is beneficial.
00:07:11.360
However, this is where our refactoring tends to stop, and that’s a problem.
00:07:16.800
Because this class evolves over time and is doing more than it should.
00:07:22.800
In reality, it looks much messier when you open it in an editor.
00:07:27.840
This complicates troubleshooting any bugs that arise.
00:07:34.000
This is where the concept of service object extraction comes in.
00:07:40.319
We need to pull out all the helper methods into a separate class, completely isolating it.
00:07:46.800
The original controller will only call this service object.
00:07:52.960
The tool I'm referring to is a gem called MethodStruct, which is about 10 or 15 lines of code.
00:07:59.759
It codifies this process, effectively removing boilerplate.
00:08:05.199
It requires you to do three things: figure out a name for the action you want to perform, identify dependencies, and implement the method call.
00:08:10.720
Since it’s a separate class, you can add all these helper methods you’d ordinarily do in plain Ruby.
00:08:16.879
You can call them either via a class method or instantiate them later.
00:08:23.680
Calling by default works seamlessly, as it functions similarly to Procs and Lambdas.
00:08:30.639
However, it also allows passing custom method names, which can be great.
00:08:36.000
For instance, if using Delay Job, it can assume the method is going to be called 'perform'.
00:08:41.599
You can actually define a separate method.
00:08:46.720
While it’s a simple concept, what we found is once we started using it in production, there were numerous benefits.
00:08:53.200
First, it compels you to label the action you're performing accurately.
00:09:00.240
For instance, the email invite for user registration is no longer just a callback in a model.
00:09:06.000
It becomes part of the business of the user registration action.
00:09:11.920
Not only must you name the methods in a way that reflects their purpose, but you also need to identify possible dependencies.
00:09:16.959
Moreover, all the extracted methods will help prevent future dependencies on what you originally refactored.
00:09:22.000
This prevents undesired dependencies on private APIs.
00:09:27.120
Following the principle of single responsibility is paramount.
00:09:32.160
Overall, this approach encourages composition over inheritance, leading to much more isolated tests.
00:09:39.600
That’s me! That’s MethodStruct, a very simple gem.
00:09:44.320
Since I have about 30 seconds left, I want to mention that ImmutableStruct is also fantastic. Thank you!
00:09:51.680
Given the circumstances, I need to introduce two new rules for the lightning talks.
00:09:57.360
Rule number one: less than 100 words per minute, which you definitely broke.
00:10:03.120
The second rule: you need to mention the word 'Java' at least once.
00:10:10.000
Ready, set, yeah, try it out! Hello!
00:10:15.760
Hi there, my name is Beatrix Zientara.
00:10:20.000
I'm a developer at Rebased. I work with Thomas and Piotr, who will be giving a presentation today on testing.
00:10:26.480
I have only one question, so I won't take up the whole five minutes.
00:10:31.680
Maybe I'll speak a little longer, but I want to ask you one philosophical question: do Ruby objects exist?
00:10:45.200
You can fill in a survey; I know you may perceive this question as stupid.
00:10:50.240
If that’s the case, please explain why you perceive it that way.
00:10:56.880
Your feedback will greatly help me, as I'll have a presentation on this topic in Warsaw next week at the Ruby Users Group.
00:11:04.079
I would be very grateful if you fill in the survey. That’s everything. Thank you very much!
00:11:12.399
Actually, you fulfilled the first rule, but not the second, so you won't be considered for the prize draw.
00:11:16.400
The survey is available on Facebook, it’s on our page.
00:11:21.360
Thank you!
00:11:24.000
What is your thing?
00:11:25.000
Ready, set...
00:11:30.000
Because it's Linux.
00:11:33.000
Ready, set, go!
00:11:40.000
Michael, Michael Grab! Hello. Yes, thank you!
00:11:45.680
So, where did ping pong come from?
00:11:51.280
There was a post by the guys from Groupon who shared some insights about things we discussed yesterday.
00:11:56.720
One guy mentioned that someone would soon know about it, pointing out some missing parts of the race, and wrote an insightful article.
00:12:06.119
And what happened was that DHH participated in this conversation on Hacker News, sharing very honest views.
00:12:14.000
He expressed his disinterest in abstract discussions but emphasized a desire to code collaboratively.
00:12:20.000
This inspired me to create a simple application for DHH, where you can submit your ideas with your code base.
00:12:26.679
DHH would then respond with his version, enabling a ping pong of code.
00:12:34.960
The plan is to select the five best entries submitted through this platform, which DHH agreed to participate in.
00:12:43.200
You can sign in via GitHub, and please provide your email for newsletters.
00:12:51.679
After a week, we'll send the selected entries to DHH and ensure he keeps his promise.
00:12:58.399
Thank you!
00:13:01.920
You didn’t mention Java! The entire thing would not have happened if the guys from Groupon had written their code in Java.
00:13:05.839
Okay.
00:13:08.720
Ready?
00:13:13.680
Set!
00:13:14.000
Thank you!
00:13:19.000
Ready, set, go! Java is cool!
00:13:24.120
Thank you, that's done! Ruby on Rails rocks!
00:13:29.280
My name is Alex, and I’m here as a devil's advocate because all day I hear Rails is not good.
00:13:35.280
I want to remind you that Rails is cool.
00:13:41.680
Who thinks that Rails is not cool?
00:13:43.000
Okay, how about Rails is cool? Everyone loves Rails!
00:13:50.000
What about REST?
00:13:51.000
Okay, let's see.
00:13:55.200
So, back in 2006-2008, Rails was brand new.
00:13:57.040
We could create a blog in 15 minutes, a shop in just a few days. It was fantastic!
00:14:04.240
And here we are, still able to do that now.
00:14:11.160
Most Rails applications don't need a separate persistence layer, and many are actually quite simple.
00:14:19.760
It’s important to remember not to over-engineer your applications.
00:14:26.000
By the way, what are your alternatives to Rails?
00:14:32.400
Who here uses Sinatra in production? Wow, more people than I expected!
00:14:39.680
It’s interesting because there is a phenomenon where every advanced Sinatra application eventually gets rewritten in Rails.
00:14:44.960
That, however, is not necessarily true.
00:14:51.040
If your application is advanced enough, you likely won’t need to rewrite it.
00:14:57.520
Rails is undoubtedly cool! Just follow a few guidelines and you'll be just fine.
00:15:04.320
Avoid using observers and things will be okay.
00:15:10.920
You might also want to reconsider overly complex filters and helpers.
00:15:17.040
In short, use Rails well, and you can avoid common pitfalls.
00:15:23.440
Remember the reasons why we choose Ruby and Rails.
00:15:30.720
Many of you transitioned from PHP because Ruby allows for cleaner code.
00:15:37.440
Furthermore, others came from Java and we know that excessive abstraction is too complex.
00:15:43.520
Let’s stick to Ruby's simplicity.
00:15:50.000
Thank you!
00:15:56.080
Thanks for mentioning Java twice!
00:15:59.040
Come on!
00:16:00.000
Ready, steady...
00:16:05.760
Whoa! It’s Linux and it worked!
00:16:11.840
That's an improvement from last year!
00:16:16.160
Hello! I would like to talk about React.js and Hexagonal JS. Has anyone developed with React.js before?
00:16:39.840
Have any of you worked with Hexagonal JS before?
00:16:44.240
We need to integrate both concepts effectively.
00:16:49.680
In our company, we use Hexagonal JS to create decoupled systems.
00:16:54.720
This involves use case adapters and graphical interfaces.
00:17:00.320
We need to glue everything together while incorporating aspect-oriented programming.
00:17:05.680
So why React?
00:17:12.160
Does anyone need an explanation of how awesome it is?
00:17:16.960
Here's how a component in React looks. It includes a simple counter concept.
00:17:24.800
We need to combine it with our use case, which accomplishes the same objectives.
00:17:31.120
The challenges arise when we try to glue it together.
00:17:38.560
After building it, we need to confirm that everything works.
00:17:43.520
Oh no, it probably won’t!
00:17:49.760
However, here's a tip: if you run into a problem where the method only activates after invoking it a second time, force an update.
00:17:56.000
When gluing components together with aspect programming, we must apply the right methods at the appropriate times.
00:18:02.080
Thank you!
00:18:07.360
Ready? Okay, set, go!
00:18:08.960
So, let's discuss randomness in Ruby.
00:18:14.080
The Random class isn’t ideal for production use.
00:18:20.800
Most developers think otherwise, but I have seen instances where this class has been utilized.
00:18:26.000
If you're employing it, here are the reasons you should reconsider.
00:18:32.000
Do you truly understand whether a series of outputs is random?
00:18:40.000
With longer samples, it remains elusive.
00:18:46.000
Ruby's random number generator, which utilizes the Mersenne Twister library, initializes with a 32-bit integer.
00:18:52.000
It generates a state as an array of 624 integers used in a shift register.
00:18:58.720
The output generation is reversible, which facilitates predictions.
00:19:05.120
To disrupt predictability, gather 624 outputs.
00:19:11.080
While it may seem challenging to reverse the equations, they can be simplified.
00:19:17.760
I will demonstrate with Python, as it's simpler to reset the generator's state in that language.
00:19:23.920
The goal here is guessing a few consecutive numbers, which are 64-bit integers.
00:19:29.760
The demonstration uses two outputs concatenated together.
00:19:37.520
Once you've acquired those outputs, you can predict the generator's future numbers.
00:19:45.200
As a result of understanding its state, I successfully predicted the outputs.
00:19:52.240
In conclusion, avoid predictable random number generators, especially those based on current time.
00:20:00.000
Also, avoid leaking random outputs, and remember to use SecureRandom for serious scenarios.
00:20:06.400
Thank you.
00:20:11.240
Ready? Set, go!
00:20:17.360
Nobody knows Ruby well, but these are simple things.
00:20:22.880
I think many of you will still learn something advantageous.
00:20:28.000
Firstly, I just learned this yesterday in IRB: you can retrieve the last evaluated value using an underscore.
00:20:34.000
Now, onto some obscure Ruby syntax: the flip-flop operator.
00:20:40.000
Watch me live code! I have a list of strings to demonstrate this.
00:20:47.248
The dot-dot here signifies a flip-flop operation, acting as a switch.
00:20:54.560
The first expression turns the switch on, while the second turns it back off.
00:21:00.960
Isn't that fascinating? Can Java do this? I don't think so.
00:21:08.160
Next, let's talk about block-local variables.
00:21:12.160
We know that if the variable already exists, it will get redefined inside the block.
00:21:18.080
However, you can scope it properly by using a semicolon.
00:21:23.680
That’s pretty neat!
00:21:29.840
Now about complicated regular expressions: explaining them can be challenging.
00:21:34.880
However, appending 'x' to the end allows for white space and comments.
00:21:41.120
This greatly simplifies complex regex explanations.
00:21:47.400
If you have a bit more code on this slide, you can see how clean it can be.
00:21:52.240
Unicode literals in strings? In Ruby 1.8, these were only character arrays.
00:21:56.920
But in Ruby 1.9, they're now treated as character arrays or code points.
00:22:02.760
This allows you to easily insert specific Unicode characters using hexadecimal.
00:22:08.000
We now have enumerators to loop over each character and perform operations, such as drop and select.
00:22:14.160
Want to define ranges in regex for those characters? You can do it!
00:22:21.920
Let’s review how we can use those Unicode code point ranges to scan strings.
00:22:29.040
Now, we can extract all Chinese characters without any problem.
00:22:34.800
Remember, with integers, you can convert them to hexadecimal using `to_s`.
00:22:41.040
And with method object calls, the responds_to method can utilize procs.
00:22:48.000
This allows enums to easily combine using simple regex.
00:22:55.040
On the command line, Ruby can function like awk.
00:23:02.160
Using the standard input, Ruby can read every line, and using '-n' assigns the line to`$_.`
00:23:08.960
You can output results by using `p` at the end.
00:23:14.560
You can even designate delimiters with `-F` for easy processing.
00:23:20.000
Time's up, but I hope you learned something valuable about Ruby!
00:23:27.600
Thank you very much!
00:23:31.679
I’ll mention Java most often!
00:23:34.760
Hello! Ready?
00:23:40.080
Thank you! My name is Michael Papis.
00:23:46.569
I run RVM, but I struggled to mention Java.
00:23:51.360
Some time ago, I faced issues with engineering.
00:23:55.920
They stopped paying me for my work on RVM.
00:24:01.200
Thanks to your contributions, we raised $51,000!
00:24:08.160
Big thanks to all who supported this project. It allows me to work on RVM until the end of the year.
00:24:12.960
Currently, we have RVM 1.25, and I probably won't add any new features.
00:24:19.920
Please adjust to this version as it will be the last one.
00:24:27.200
If any problems arise, feel free to report them!
00:24:33.040
As long as RVM 2 is not released, I will fix issues for RVM 1.
00:24:39.520
I had some downtime while troubleshooting RVM 1, but I've also played Warzone 2100.
00:24:46.400
It's an open source game available for Windows, OS X, and Linux.
00:24:55.200
Give it a try! If you have any questions, I’ll be at the party, so feel free to chat.
00:25:00.800
Thank you!
00:25:06.240
So who's left? Is anyone else here?
00:25:09.560
Okay, ready, go!
00:25:12.640
Thank you! Well, I heard some laughter.
00:25:20.000
It's hard to solve the problems with Wi-Fi. Kudos to the hosting team!
00:25:27.720
They did a commendable job!
00:25:32.160
They provided proper hardware that actually works with Java.
00:25:38.160
They also did not implement a captive portal like they did last year.
00:25:44.240
This greatly reduced issues attendees faced.
00:25:49.120
With the captive portal, everyone was blocked.
00:25:53.120
Another issue arose with the subnet mask. It can only handle 120 users.
00:26:00.000
There's a limit on the number of connections on the network.
00:26:05.920
It’s important to keep this in mind.
00:26:12.240
If you really want to provide fast and reliable Wi-Fi, consider using a 5GHz network.
00:26:18.560
That’s still empty and underutilized.
00:26:21.680
However, it's crucial to have enough access points to serve 300 people adequately.
00:26:32.000
Additionally, I’ll touch on smaller tips, such as why mounting Wi-Fi under your seat is effective.
00:26:38.399
You can read my blog post about it.
00:26:43.440
Thank you!
00:26:49.920
Hello! I’m Matt.
00:26:56.000
I run a consulting service called The Software House.
00:27:01.320
Today, I played this game and was very close to winning.
00:27:06.720
Besides playing games, we build a lot of fun stuff to get paid.
00:27:12.000
We usually work with foreign clients, so getting paid in several currencies can get tricky.
00:27:19.680
Let’s talk about how to receive payments without getting ripped off!
00:27:25.440
Clients often prefer PayPal, but my experience with it may vary.
00:27:30.000
There are usually hefty commissions involved, around 3 to 4 percent.
00:27:35.760
They also often make you convert currencies to withdraw funds.
00:27:41.360
That’s where you might end up losing a lot of money.
00:27:46.800
Avoid receiving wires in euros to a Polish złoty account!
00:27:51.120
We lost a considerable amount of money due to previous mishaps.
00:27:55.680
The best option is to set up a dedicated currency account for wire transfers.
00:28:01.600
Using online exchange services can help minimize costs.
00:28:06.320
Wire transfers often range between $20 to $50 and are pretty fast.
00:28:12.239
Alternatively, you could use Authorized.Net or another card processor to handle credit card payments.
00:28:17.920
This may incur lower fees of about 2 to 2.5 percent.
00:28:23.680
Clients appreciate using credit cards, but setting it up can be a hassle.
00:28:29.920
Especially if it involves quite a bit of paperwork.
00:28:34.000
Furthermore, once set up, you still need to handle currency conversion.
00:28:39.240
Finally,
00:28:49.680
if you frequently pay for services like GitHub or Jira, consider using cards in euros.
00:28:55.760
Thank you!