00:00:25.519
All right, good morning, everyone! After the bright talk this morning by [insert name], it's time to get dark.
00:00:33.680
I'm from Joe Software, and I started this journey in 2007. These are my Twitter handles.
00:00:46.000
As an author, I have a couple of books out, but it doesn't look so dark anymore, does it? So what is my talk going to be about? Don't worry, it's not going to be anything scary!
00:01:05.119
I love Ruby, but as with every relationship, you need to accept its dark side. Just like in marriage, you might discover aspects you weren't aware of while dating. It's the same with Ruby; you have to be aware of the quirks.
00:01:24.520
In my talk, I will highlight the weirdness and gotcha moments. If you find those 'AHA' moments as we go through, then my talk is succeeding. We have a varied audience today, so to ensure everyone's sanity, I've tagged my slides.
00:01:40.600
The slides are tagged for beginners and experts alike. Beginners must pay attention, while experts should try to encourage beginners to answer the questions. Remember, learning is the goal, so let’s get started!
00:02:08.440
Now, let's talk about the infamous Infinity.
00:02:13.680
We all know what Infinity is, right? Since we are all programmers, we should know the answer. The answer is simple: division by zero.
00:02:25.680
But wait, what about this case? This actually works! Everything in Ruby is an object, so let’s see what that looks like.
00:02:36.239
Infinity is a constant defined in the Float class. However, you might not see it right away. You can use this constant for range comparisons and equality operators. Imagine using 3 == Infinity, and guess what? It works!
00:02:54.519
This is how I get people warmed up. Let’s do something with a bit more adrenaline: base conversions. So, what do you think the output will be for this conversion? I don't want the math geeks to rush to their calculators.
00:03:15.840
The essence here is converting a number to a string in octal format. Should be manageable, but let's see how you do.
00:03:40.080
And yes, it actually works! The next time you're reading about terms like 'geta fix' or 'Vital Statistics,' remember, a number can also serve the same function. You know, we can push the limits!
00:04:08.920
Logically, however, the radix support goes only up to 36 because we have 26 alphabets and 10 digits. So if there are innovative minds out there, we could invent a new alphabet and raise that to 37!
00:04:20.959
Now, let’s move on to the star operator. To begin with, let’s see what it does with the splat expander.
00:04:51.120
Here, we have a Struct with two elements: name and occupation. I've created an object of this struct.
00:05:05.360
Nothing fancy yet, still looking good. The splat expander has successfully taken my arguments and assigned them correctly.
00:05:10.400
But as real programmers, especially in Rails, we usually deal with keyword arguments. Let's look at this: what do you think the output will be? Now, it’s Optimus Prime!
00:05:37.240
The output here has changed because the Struct always treats input as an array of arguments. This behavior is different in classes.
00:06:02.479
Let’s look at something more humorous: how to convert an array into a hash. Raise your hand if you've used this notation before.
00:06:09.120
Excellent! But what happens if I have a seventh element in the array?
00:06:14.319
We might run into an error. In this case, what do the rest of you think the output will be? Who thinks it will be 3, 6, and N?
00:06:39.000
Awesome, right? That wasn't too hard! Now let's look at string concatenation and see how that works.
00:06:51.520
How many of you have seen our friend, the stabby proc? Here's an example. This stabby proc takes arguments, but if I invoke the block like this, what will be the output?
00:07:16.120
Mumbling it out, it's five! Now, you probably knew that already. The structure basically accounts for the first, second, last, and the remaining stuff is in the middle. It’s quite a helpful thing to know.
00:07:48.840
This concept applies not just to stabby procs, but also to regular procs, lambdas, and methods. However, while exploring these features, I learned something new.
00:08:12.000
What do you think is the output of this code? It works, but I have no idea how. Let's review this, and if someone can explain how that dot notation functions, I would appreciate it.
00:08:37.720
Let’s dive into case statements. Have you all used case when in Ruby? I’ve tried to make this example as complex as possible. If it's Optimus Prime, doesn’t it?
00:09:10.160
So what is the expected output? It’s clear that we have a multiple of three, as nine is a multiple of three.
00:09:27.440
Ruby provides readable code, so we can easily decipher the answer. However, my question is: 'multiple of' is a method. It takes one parameter. How was it compared with nine, and where did that nine come from?
00:09:49.519
Behind every case statement is a case equality operator that effectively connects these two. The integer nine used with a case equality operator yields this output.
00:10:20.520
Even though this seems straightforward, it grants immense power. This feature allows me to manipulate the case equality operator simply by overriding the == method.
00:10:49.160
Let’s discuss equality now! How many of you are familiar with the symbols and operators: ==, ===, eql?, and equal?
00:11:06.440
Let's have some fun! Who thinks this expression will yield true? And who believes it will yield false?
00:11:34.760
There seems to be a majority for 'false,' but let’s clear this up. The result is indeed 'false.' This comparison is between object IDs of an integer and a float. They are distinct objects!
00:12:01.160
For example, string 'a' and string 'a' are two different Ruby objects. However, if we switch that to a symbol, they become the same!
00:12:33.320
Now, let’s discuss currying. How many of you know what currying is? It's quite fun. To make it more fun, I decided to implement a slot machine example.
00:12:51.600
The code I wrote on my flight here is a bit uncertain, but it compares three pulls to see if they're equal. Do you think that will work?
00:13:20.240
Currying is a method in the proc class that returns a lambda if all parameters are not fulfilled. In my example, with three specific parameters, the invocation in square brackets returns a lambda.
00:13:52.560
However, when all parameters are fulfilled in the second statement, it evaluates the proc correctly.
00:14:16.640
This approach saves you from waiting for user input via gets. Instead, you can directly evaluate it, making everything significantly efficient.
00:14:41.799
Let’s discuss private methods. We've all learned that private methods are not inherited. But, what if I told you they are inherited in Ruby?
00:15:07.560
This is a fundamental principle of Ruby that challenges traditional Object-Oriented Programming principles. Every property of private methods comes along with inheritance.
00:15:40.160
Now let’s pose another question: what’s the difference between include, which we’ve all heard of, and protect methods?
00:16:09.959
Include is a private instance method defined in the class or module, while protected methods can be invoked on other objects within the same lineage.
00:16:44.560
To put this in perspective, if I define the initializer in one line, what will be the output?
00:17:05.920
Well, if it did not work, I would have not added this slide again. It works! But why does it work? The key here is the object lineage.
00:17:47.520
When invoking a protected method, I can do so because I am in the Autobot class, and I'm calling a method on the Prime object, which also belongs to the Autobot class.
00:18:31.600
If I were to use 'prime.nick' outside of this scope, it would fail as it would be in a different context.
00:19:07.240
Let’s explore languages with keywords. When we call a function, how often do we think it leads to a syntax error?
00:19:26.400
How many think this will trigger a 'stack too deep' error? I'm curious to see how many believe it will.
00:19:56.520
Not at all! This actually works because true's resolution is immediate. However, if I changed those statements to self.taut false or self.taut true, it would cause a stack error.
00:20:32.360
If that wasn't enough complexity, let’s discuss modules. Suppose I have a Megatron module with immense powers, and I want to integrate those with my Hanuman class.
00:20:59.280
This integration poses a challenge. While Hanuman could be as powerful as Megatron, blending the two ideologies might not be socially acceptable.
00:21:39.560
How can I cherry-pick attributes from Megatron without compromising Hanuman's ideals? I would require the specific method.
00:22:02.480
By utilizing a defined method to call power, I can select the method I want and bind it to the class instance.
00:22:28.280
This method reinforces the importance of class design in Ruby. We are now empowered to utilize Megatron’s capacity without changing Hanuman's nature.
00:22:52.240
With that, I conclude my talk and thank my two assistants, who supported me throughout.
00:23:25.140
I am open for a few questions. Do I have the time, guys? Do I have some time for questions?
00:23:46.560
Thank you! Do we have a question? What led you to title this talk the 'Dark Side of Ruby?'
00:24:20.280
The title embodies two meanings: firstly, it cleverly fooled the organizers to accept my paper, but more importantly, it represents the hidden quirks of Ruby.
00:24:53.600
Just like the 'Dark Side of the Moon,' it's important to acknowledge the tricks and moments that might be missed but are significant in the grand scheme.
00:25:23.400
Yes, any other questions? Absolutely, I have encountered various pitfalls and 'gotchas' through experience.
00:25:47.960
These findings are a mix of experience, training, and preparation for my talk.
00:26:12.760
I included aspects like Oniguruma games and method missing, along with a plethora of weirdness—all of which couldn’t be covered due to time constraints.
00:26:44.680
If anyone encounters interesting Ruby quirk or concept, I invite you to send me a tweet or email. I’d love to improve my talk with your insights.
00:27:06.560
Now, onto the question about best practices to avoid these pitfalls. These aren't problems to be averted, but rather, qualities of Ruby that enhance our understanding.
00:27:35.840
Learning about the distinctions of protected and private methods indeed sharpens our skills, making us better programmers.
00:27:59.560
Best practices exist in Ruby, such as synchronized controls. There's flexibility, but with great power comes great responsibility.
00:28:19.560
Everything comes with the understanding that Ruby allows maximum flexibility in building our code. The question is the proper use of these tools.
00:28:45.240
Are there good parts of Ruby, akin to the good parts of JavaScript? While there is a mysterious aspect, Ruby remains a language to be admired, with its closures often misunderstood.
00:29:09.280
Learning Ruby advances one's programming skills significantly, especially when starting with Ruby before transitioning to Rails.
00:29:32.880
To keep the conversation engaging and productive, check out opportunities like exorcism.io or Ruby Golf.
00:30:01.680
Taking on challenges by limiting our coding strategies can reshape your understanding of Ruby and push your abilities further.
00:30:25.760
Is there any last question before we wrap up?
00:30:48.040
The distinction between protected and private methods immensely helps contextual understanding. It directly influences how we approach inheritance.
00:31:08.560
In Ruby, everything is object-centric. The design allows for a nuanced understanding of inheritance, which becomes evident in practice.