Metaprogramming

Ruby 2 Methodology

Ruby 2 Methodology

by Akira Matsuda

The video titled "Ruby 2 Methodology" features Akira Matsuda's presentation at RubyConf 2015, focusing on the evolving concept of methods in Ruby. Matsuda provides an in-depth examination of modern usages of Ruby's methods, highlighting new features and sharing personal insights alongside practical examples.

Key points discussed in the video include:

  • Definition of Methods: Methods in Ruby are defined using the 'def' keyword, with the possibility of unconventional names, including emojis, which can enrich the method naming experience.
  • Dynamic Method Calls: The 'send' method allows dynamic method calls and enables calling methods from outside scopes, enhancing flexibility in method invocation.
  • Method Scopes: Ruby includes three method visibility types: public, protected, and private. Matsuda shares insights on correctly using private and protected methods, encouraging developers to use protected sparingly.
  • Method Documentation Issues: Challenges in method documentation arise due to the behavior of the 'private' keyword and the inadequacies of RDoc. Matsuda discusses the need for patches to improve documentation consistency in Rails.
  • Method Objects: Method objects allow methods to be extracted and bound to different classes, facilitating method transplantation, which is useful for Rails monkey patches.
  • Parameters and Keyword Arguments: Ruby 1.9's parameter inspection and Ruby 2.0's introduction of keyword arguments simplify method parameter handling and enhance API design. Challenges with reserved keyword conflicts are acknowledged.
  • Module Prepend for Monkey Patching: Matsuda explains how module prepend offers a better alternative to legacy alias method chains, resulting in a cleaner approach to monkey patching.
  • Super Methods and Refinements: With the introduction of super methods in Ruby 2.2 and refinements in Ruby 2.0, developers gain better control over method inheritance and private methods, reducing the pollution in the method namespace.

In conclusion, Matsuda stresses the importance of engaging with these evolving features of Ruby methods to enhance programming practices and the overall Ruby experience. He encourages developers to keep exploring these advancements to enrich their Ruby development journey.

00:00:11.990 Let me start my talk by repeating that this session focuses on the concept of methods in Ruby.
00:00:17.610 I apologize in advance as this talk will be a serious, pure Ruby discussion.
00:00:25.740 You know, RubyConf has various session tracks this year, such as main patterns, less code, and in-depth discussions. I think it's well-balanced with diverse topics.
00:00:38.430 It's a matured conference, but I am glad that RubyConf still has an in-depth Ruby track. By the way, I guess you've heard about another conference called Ruby Kaigi in Japan happening next month.
00:00:51.630 Thank you. Is anyone coming to Ruby Kaigi? Not so many, but thank you for being here! The conference website looks great. It’s a three-day conference with two tracks each day, making it a total of six tracks.
00:01:08.730 All six tracks will focus solely on Ruby. Everyone talks about Ruby because that's what Ruby Kaigi is about. If you want to see more Ruby talks, I'm sure Ruby Kaigi is the conference to attend.
00:01:17.400 I guess you all want to discuss Ruby, which is why you are here, right? Let’s get started. The conference is organized by these individuals, and I am at the very top as the chief organizer for Ruby Kaigi this year. My name is Akira Matsuda. You can find me on GitHub as a matzoda, and I work with Ruby on Rails as well as several other open-source projects and consulting for various companies.
00:02:06.060 This talk will focus on methods in Ruby. I will discuss some modern usages of Ruby's methods, not only introducing these features but also sharing my own experiences and interesting stories along with many cool examples.
00:03:08.840 To define a method, we typically use the 'def' keyword. For example, we can define a method named 'hello'. However, sometimes we wish to define methods with unconventional names, such as using emojis.
00:03:38.290 For instance, can a method name contain emojis? The answer is yes, you can define a method using emojis, and it is perfectly valid Ruby code! You can see an actual example of this in the 'active emoji' gem where it shows usages of emoji in method names.
00:04:10.239 You can simply call methods with their emoji names. However, not every character can be used in a method name. For example, characters like '1', '2', '3', '?', '@', ':', and ';' may cause issues.
00:04:26.680 Defining a method with '@' in the name, for instance, will result in a syntax error. To create a method like '@', you can define it in a certain way—catching the error when trying to define invalid characters.
00:05:06.220 This can become quite creative! The result could be something like this: "> , `, $, 1, 2, 3, 4, and other complex symbols can be defined using 'define_method'.
00:05:37.320 To call these methods, you can use 'send' which allows for dynamically defining method names. This means you can call those methods with symbolic names and it also facilitates calling methods from an outside scope.
00:06:00.710 For instance, within a Rails controller, you can dynamically call a private method. When discussing method scopes, there are three types: public, protected, and private. Public is the default and open to everyone while private methods cannot be called with a normal method call.
00:07:10.949 You can call a private method from inside the class, but if there is a local variable with the same name as the private method, the local variable will take precedence instead of the method.
00:07:35.550 To explicitly call the private method in the case of name collision, you can use parentheses with the method call. Although it works, it may resemble JavaScript syntax, which some may not prefer. Another way is to prepend 'self.' with the private method, but this may also lead to 'no method error' since it restricts the access to private methods when they should actually work.
00:08:53.760 Due to this restriction, a patch was created to allow private methods to be called with 'self.' but as of Ruby 2.3, this patch hasn't been merged. Another solution when encountering this situation is to change the scope of the method to 'protected.'
00:10:01.860 In Ruby, protected means that you cannot call methods from outside except from another instance of the same class. I have encountered many instances in Rails where protected methods have been used incorrectly, and they should actually be private instead.
00:10:33.840 I authored a patch that replaced around 150 instances of protected methods with private, which all still passed tests, suggesting that most uses of protected intended to denote private methods. One real use case involved action controller parameters where you sometimes need this to call the permitted method of another instance.
00:11:44.640 My advice is to avoid using protected unless you are sure you need its behavior. I found documentation issues when documenting methods in Rails since RDoc generates documentation hierarchies for public and protected methods but not for private ones.
00:12:02.820 This patch has spoiled some documentation within Rails. We encountered another issue with documenting methods; the 'private' keyword introduced since Ruby 2.1 can cause empty documentation when generating RDoc.
00:12:59.820 These issues have already been filed on GitHub, and we need a patch to prevent this from happening. Additionally, I want to discuss method objects, which provide another way to invoke methods.
00:13:55.050 For instance, you can extract a method object from a class or instance. When you want to call an unbound method, you need to bind it to an instance of that class. For example, trying to call an unbound method from a different class will not work.
00:14:49.650 However, Ruby introduced a new feature called method transplantation, which allows you to unbind a method from one class and bind it to another class. This allows for a more flexible way to include specific methods from modules without including them entirely.
00:15:40.750 You can also extract methods from a class and bind them to another class, which is quite useful for writing Ruby on Rails monkey patches.
00:16:51.130 Now let's move to parameters in methods. You can pass parameters to methods, and starting from Ruby 1.9, it allows you to inspect the parameters of a method directly.
00:17:54.170 This feature was implemented by the Ruby core team, primarily by a member named 'Katsuma' who also contributed to several improvements surrounding method parameters.
00:18:49.590 As an example, a Rails plugin I created allows controllers to accept parameters more intuitively, thus streamlining how you handle incoming data.
00:19:25.960 Ruby 2.0 introduced keyword arguments, allowing for cleaner APIs as compared to traditional methods. This improvement was also a contribution of Katsuma, who is well-known in the Ruby community.
00:19:51.720 Here’s the output of method parameters for keyword arguments. I highly recommend using action arguments as they offer a great functionality that I can no longer live without when working on Rails applications.
00:20:29.230 A potential challenge with keyword arguments is that they cannot ever access local variables where the keyword is a reserved word, which can lead to confusion and errors in some cases.
00:21:53.030 Another aspect to discuss is the deprecated alias method chains for monkey patching since Rails 0.
00:23:05.090 It was more of a hassle than an advantage. With Ruby 2.0, a new feature called module prepend allows better support for monkey patching.
00:24:01.900 I'm excited about this change, as it helps developers avoid some pitfalls associated with using alias method chains.
00:25:00.090 The concept of super methods, especially in Rails, becomes crucial as multiple inherited calls can make it hard to read through your code and understand the flow.
00:25:49.440 Using Ruby 2.2, the super method introduces a way to find which methods are called, which can help in debugging and production.
00:26:53.090 Sadly, not everyone uses super methods effectively, which is understandable considering they are still quite buggy.
00:27:32.490 However, one must consider that when working with multiple super calls that it leads to complexity. Refinements introduced by Ruby 2.0 make monkey patching less polluting.
00:28:41.870 Refinements allow you to create methods that are private and expose them only when they are needed.
00:29:49.480 This feature is especially useful when extending frameworks or defining internal logic that doesn’t need to be publicly accessible.
00:30:53.520 In conclusion, refinements may have some limitations, but they present a cleaner way of implementing monkey patches without exposing every method to users.
00:31:37.900 I believe Ruby's methods are continually improving, so I encourage everyone to engage with these new features and contribute to making Ruby even more enjoyable.
00:32:08.300 Thank you very much for your attention.