Talks
The Dark Side of Ruby
Summarized using AI

The Dark Side of Ruby

by Gautam Rege

In the talk "The Dark Side of Ruby" by Gautam Rege, delivered at Garden City Ruby 2014, the speaker explores the peculiarities and complexities of the Ruby programming language. Aimed at both beginners and experts, Rege emphasizes understanding Ruby's quirks, which can often lead to 'A-ha!' moments during programming. Key points discussed include:

  • Infinity in Ruby: Rege explains the concept of infinity, specifically how it is represented in Ruby's Float class, and gives examples of equality comparisons utilizing infinity.
  • Base Conversions: The speaker introduces the idea of converting numbers into different bases, highlighting the limitations of radix support.
  • The Star Operator: Rege illustrates how the splat operator can be used for argument expansion and shows how keyword arguments behave differently.
  • String Concatenation and Stabby Procs: He introduces stabby procs, demonstrating their functionality and the differences between them and regular procs and lambdas.
  • Equality Operators: The distinctions between ==, ===, eql?, and equal? are clarified, with examples comparing object IDs and the implications of different comparisons.
  • Currying: Rege discusses currying in Ruby, using a slot machine example to show how it can form lambdas from partial arguments.
  • Private and Protected Methods: He challenges traditional Object-Oriented Programming concepts by revealing how private methods can actually be inherited in Ruby.
  • Keywords and Modules: Rege dives into the use of keywords and shows how to cherry-pick methods from modules while discussing their integration.

Concluding his talk, Rege reflects on the reasons behind the title "The Dark Side of Ruby," noting the hidden complexities and quirks that developers must acknowledge. He encourages programmers to embrace these challenges to enhance their Ruby skills and understanding. The take-home message highlights that the so-called 'dark sides' are integral to mastering Ruby and that with great power comes the need for great responsibility in programming decisions.

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.
Explore all talks recorded at Garden City Ruby 2014
+20