 Let me start my talk titled Ruby to Methodology. This talk focuses on method in Ruby. I'm sorry, but this talk is going to be a serious, pure Ruby talk. You know that Ruby Conf this year has these session tracks, like domain patterns, less code, but we're rubies, et cetera, et cetera, et cetera. And I think it's very well balanced, diverse topics. It's so matured conference. But still, I'm so glad that Ruby Conf still has the Ruby in-depth track. By the way, I guess you've heard of another conference called Ruby Kaigi in Japan, which is happening next month. Yes? Thank you. Thank you. Who's coming to Ruby Kaigi? Raise your hands. Not so many, but yeah, thank you. Thank you, guys. So the conference website looks like this. The conference is a three days conference and it has two tracks per each day. So it kind of has six tracks. And all of these six tracks will be just about Ruby. Ruby, Ruby, Ruby, and Ruby. So at Ruby Kaigi, everyone talks about Ruby because it's a Ruby conference, right? If you want to see more Ruby talks, I'm sure Ruby Kaigi is the conference you should go. Okay. And I guess you all want to talk, I mean, hear about Ruby. So that's why you are here, right? Yes, so come to Ruby Kaigi maybe next year. And the conference is organized by these people and I'm at the very top as the chief organizer of Ruby Kaigi this year. So that's me. My name is Akira Matsuda. I'm on GitHub as a Matsuda. I work for Ruby, Ruby on Rails and several other open source products and consulting several companies. So, all right. I said this talk focuses on method in Ruby. I'm gonna talk about some modern usage of Ruby's method and I'm not just introducing these features like reference. I'd like to tell my own stories. I'd like to tell how I'm concerned or what I did or what I'm doing with these with lots of code examples. So let's start with the method definition. To define a method, of course, we use def, for example, like this, def hello. And, but sometimes we want to define a method with weird names like not like hello, for example, like emoji. Let's say, can a method name contain emojis? Who thinks that you can do this? Okay, okay, thanks. The answer is yes. You can do like def beers. It's perfectly valid Ruby code and you can see an actual code like this in SFRX active emoji gem, which looks like this. At the bottom it has like def 10, def 100, et cetera. And it works. And you can just call these methods with their name like both beers, all right. Then, which character cannot be a method name? You can imagine like some of these ASCII characters like one, two, three, or question mark, at sign, colon, semicolon. There might be invalid method name, for example, defining an at sign method. This causes a syntax error. So how can we define an at sign method without using C extensions? Actually, do this a lot in my application. This is a real code example for my application, defining at sign, exclamation, colon. So, to know which character is invalid method name, just simply just try to define the method and catch the error and the result becomes like this. Like space, back quote, dollar, one, two, three, four, at sign, square bracket. All of these can still be defined by a defined method. So how can we call this method? Of course, we have colonel send. And that at sign method can be called by send. And colonel send is actually not only used for calling these abnormal name method, but also for like determining the method name dynamic dynamically or when calling a method from outside scope. This is an example of dynamically changing a method to call. It's taken from Rails action controller. And another example of calling a method from outside scope is like this. It's defining a private method and calling it via send. So, what is method scopes? There are three types of method scopes, public, protected and private. Public is, of course, the default scope open to everyone. And private is like this. You cannot call private via normal method call. It's very simple, okay? And what's this? Yeah, you can call the private method by from the inside the class, right? But if there is a local variable with the same name, the private method will never be called, but just the local variable will be called. So, how to call the method? You can put parentheses to say that to like, to call the method, not the local variable. Well, it works, but it looks like a JavaScript. So, no thank you. Another way to call the private method is to prepend self. for this work. Unfortunately, no, it raises no method error. We hit this situation on a real application at UB Regi. So, we changed a public method in Rails controller to be private. Then we saw this no method error because we put self. And it worked, and it used to work while the method was public. And I think this should not be an error. So, we wrote a patch like this. Allow private method with self. This was written by this guy, Sotaro, and Matt accepted this. It's okay to merge. That's what he said. But, I'm sorry, I forgot to merge this in, and he said, please do the documentation, but I had no time to do this. So, the patch is done, but it's still not included in 2.3. Maybe it's coming in 2.4. Well, another way to call a method with self. is change the scope to protected. Protected? So, what exactly is protected? Who can explain? Who here can explain? Protected is like familiar in Java and C++, but Ruby's protected is different from these. And, well, it can't be called from outside, like private, but it can called from other instance of the same class. That's the difference between private and protected. So, who uses this feature? I searched for a real-world use case in Rails. As you know, Rails includes so many protected. I saw more than 200 use cases, 200 occurrences of protected in Rails, and I found almost all of these are wrongly used. I mean, actually means private, so I wrote a patch. To replace 150 protected to private, and it still works, but all the test passes. So, that means more than 90% of protected in Rails code actually means private, and the rest, like 20 or 30 use cases. This is the real use case of protected. Action controller parameters, dupes, and it calls the permitted method of another instance of duplicated parameters instance. This cannot be done if the method is private. So, my advice is don't use protected unless you're sure you're calling protected method, okay? However, again, this patch is still not merged, because the patch has the problem, the rdoc problem. rdoc mutes private methods documentation. For example, if you have these methods and documentations, like public, predicted, private, the rdoc generates documentations for, sorry, public and protected, right? And does not generate documentation for private methods. So, my Rails patch spoils private methods, there's so much documentations in Rails, that's not good. So, this was the story of how we abuse protected and why still we need protected in Rails. And by the way, we found another rdoc problem in Rails. Consider we have this class, like public def, protected def, private def. This is introduced from, I guess, 2.1. So, generating rdoc from this class generates empty documentation. And even worse, if once private was defined, the rest of the methods become empty. This was already filed on GitHub, rdoc rdoc, so we need a patch. Unless this issue is solved, we cannot use this syntax, private def. So, we're looking for a patch. Please. And so, the next topic is method objects. Another way to invoke a method, other than calling the method or sending to method is method call, call method of the method of objects. You can inspect an object's method like this. And you can extract a method object from a class or instance. And you can call it this way. You can also pass in a parameter. This is how you can get a method object from the class, not from the instance. It's actually called unbound method. It's kind of method, but you cannot call the unbound method. In order to call the unbound method, it's kind of different. So, in order to call the unbound method, you have to bind to an instance of that class. For example, there's a person class and cat class, and each of these defines hello method. And are these hello method an instance of that? Yes, there is no. It causes type error. So, you cannot unbind a method from a person and bind it to a cat. It causes an error. But, here's a new feature of Ruby 2 called method transplanting. Well, you can unbind a method from a module, then bind it to a class. That's called method transplantation. It's nothing different from including the module directly into the case, into the cat in this case, but it's kind of cherry picking a method without including the whole module, right? And, more new features in Ruby 2, too, is you can cherry pick a method from a class and bind to another class. Only if the method is from a module, originally comes from a module. This is so much useful for writing Rails monkey patches because Rails has so many modules with so many methods. So, you can just cherry pick any method from modules and then put into your own class, right? Another topic is parameter. As I said, you can pass in a parameter to method call. So, what's the parameter? It's like passing something from outside and you can use the variable inside the method just like a local variable, right? So, how can we know what kind of method does a method, I'm sorry, parameters of the method take? Ruby 1.9 has method, parameters method implemented by this guy. Koichi. He's, of course, you know, you know who they were all. He's the author of Ruby 1.9 VM called garb, who's employed as full-time Ruby committed by Heroku. So, this is what's happening when you call methods parameter. It returns from sort of array over array, something like this with an optional parameter and like this for args in block. So, how can we use this? I'm gonna show you a real-world example of using this method parameters. Let's say Rails plugin written by me and it's kind of something to make your Rails controller like Merbs controller like this. With this plugin, you can make your Rails controller to take a parameter. So, you don't have to access the parameters thing, right? And it supports filters before actions as well. So, and it supports keyword arguments as well. So, what's keyword arguments? It's a new feature since Ruby 2.0 implemented by this guy, Mame. He's, I guess, kind of known as the author of this thing. Quine relaying for 100 programming languages So, this is the output of method parameter for keyword arguments. It's labeled like key and key rest. So, I recommend you all to use action args. It's very good. Actually, I cannot live without this when working on Rails application. So, please try. And by the way, I tried to bring keyword arguments into Rails itself like two, three years ago. I tried replacing some methods into keyword arguments like this. Can you see this? I'm sorry, it's a little bit hard to see. Anyway, it's very much like clean, clear API. However, I found a specification bug on keyword parameters in Ruby 2.0. You know, Rails takes, sometimes takes like, if or unless keyword and it cannot be a keyword argument for Ruby 2.0 because as I told you, an argument, the parameter is basically a local variable and local variable in Ruby cannot be accessed, it causes syntax error. So, you cannot define a argument. I mean, method parameter with a keyword, label lazy keyword, right? But strangely, you can do this by a keyword argument. Yes, reserved word, reserved word can be a keyword. And you can actually call this. You can pass in a if parameter into this method. But I said, you cannot access to this variable. So, how can you use this? Which means you can create a local variable, but you cannot touch it. It's totally useless, right? This is what happened in Ruby 2.0. So, I reported this problem and Koichi and Nobu fixed this. Nobu, of course, the patch monster. So, how he fixed this? We introduced a new feature called bindings up local variables and bindings up local variables get. Now, you can access the example of the variables get. Now, you can access the if variable this way, right? Another problem of keyword argument was performance. It used to be very slow because it internally creates hash instance, breach method call, but Koichi fixed this in 2.2. He refactored the implementation and made it fast. So, I guess in Rails 5, which probably will come in soon, it supports Ruby only 2.2 and 2.3, and it's a major version bomb, so it's a good chance to break the API. And now, we have a way to access the if and unless variables, and I think it's fast enough. So, I guess it's ready to introduce keyword arguments into Rails. It's ready to, it's time to finish my patch, but I'm sorry I had no time to work on this, I guess, until Rails 5. So, someone please take this. Now, the next topic is modular band. Yes, Rails 5. Talking about Rails 5, alias method chain is deprecated. Yay! For those of you who don't know what alias method chain is, it's a monkey patching idiom since Rails 1. Actually, Rails 0.0 something. The very first implementation looks like this. It's just an alias method and alias method, and this is how you use this. So, you can override the save method and add some new feature like validation. This is the example. After calling the, after monkey patching, then calling the save method, it outputs validated and saved. And you still can call the unmonkey patch version the method that returns save only. It's named save without validation. It's very handy, right? And it's very intuitive method name, save without validation, return saved, but it actually has the dark side. The dark side is save without validation and it doesn't always act as it really means. What if we have another chain, like callback? Now the save method does save, sorry, callback and validation and save. And let's call the save without validation method. It's not only skipping the validation, it also skips the callback, right? So, it's such harmful. Save without validation doesn't only skip validation in some cases, and you cannot tell which case, right? So, the without method is just harmful. Don't call this and don't even define this. So, we think we needed a nicer language support for monkey patching instead of alias method chain and that was introduced in Ruby 2.0, called module prepend. How it works is basically like a reverse-ordered module include. Module include is like this. You can include the validation functionality into the original save. And this is module prepend. You can do the same way, but you can call, I mean, you need to call super from the included module, I mean, prepended module. This is how it makes it called code clean. Like this is the real-world example of using module prepend. All of these used to be alias method chain, so there used to be tons of method definition, but using prepend, it just looks like, you know, the only method defined here is render. And, yeah, it's very simple, very clean, right? So module prepend always comes with send, I mean, like this, send prepend, because it was initially designed in the same way as module include, but I felt it's unnatural because it's for monkey patching and monkey patching is always done from outside. So why can't we call module prepend from outside? So I proposed to make module prepend and include public for Ruby 2.1, and it was accepted by Matz. So you no more have to, like, send prepend or send include in Ruby, in recent version of Ruby. This is done by myself. And next topic is super, super method. This is numbers of super in Rails. It's so much heavily used because it's how Rails is designed. But since there are so many, like, dev save, super, dev save, super, dev render, super, dev render, super, it's so hard to read through and it's so hard to debug, like, you know, seeing the stack trace, there are so many save, save, save, save, save, save, like this active record has so many super. So, for example, when reading code and finding super, how can I imagine, like, that super calls which super? So there's a new feature in Ruby 2.2 called super method. It returns a method object, which will be actually called by super. It's initially designed for debugging purpose, but I found that it's useful, not only for debugging, but for production code. So let's get back to Alias method chain. I said there's no way calling save without validation because there's no save without validation method defined in module prepends. But actually, it's not true. You still can call the super method because it's the same method object and you can call the method object. So this is how you can call the save without validation in module prepends. So what if we have two modules prepended like this validation callback? You can call super methods super method and still you can call save only, right? So what if you have n modules prepended? Now, method has owner, which returns the owner called super method. So it returns something like this, the module name, I mean module. So you can iterate the super method until the owner returns the target class, right? And to generalize this a little bit, you can monkey patch method object like this call without validation. You can call without validation using this method. So you can still something like a list method chain if you want to do it. But sadly, I guess nobody uses super method because it's still so buggy and nobody reports the bug. For example, unbought method has super method but it returns nil for some reason. It's just a bug. And by the way, I already reported this and module prepend plus super method it should return nil but it loops between the class and module. So it's another bug. It should be fixed I guess hopefully before 2.3. I guess I have five more minutes to talk about refinements. Module prepend is a great tool to monkey patch. It's less polluting than a limit of chain and it only can override an existing method in the target module. But that's not always the case. What if we want to monkey patch some class and include some module and define a method, some kind of private method there and we don't want to expose that internal method to the users? For example like this. Extending some framework and doing some business logic, defining some logic inside and we don't want to expose the bar method to users. How can you do this? For this purpose we can use refinements. Refinements is introduced from Ruby 2.0 by Shugo-san, who's Matt's boss and it used to be something more powerful but the recent version of refinements is kind of file scoped monkey patching tool. So this is how you use refinements. For example, defining a monkey patching method to a string, you can call this method only when using, I mean declared to use that module. So I'm going to show you the real-world use case of refinements. It extends Rails action controller base and I define several methods there but these are not needed for Rails, essentially. So I define these methods only for internal use inside this Rails plugin. So I use these methods in another file in the Rails plugin using using and these are never exposed to the end users. So this way you can create very, very clean monkey patch. I would call this super private method. These methods will never expose to the end users. And exploring this feature I found some pitfalls of refinements. You cannot call the refined method by a send or public send but we very often want to monkey patch some method which is very often called by a send, particularly in Rails. So I really want to call the refined method in Rails but I still want to use refinements for my Rails monkey patching plugins. I think this restriction is too hard and should be losing in my opinion so I requested to please loosen this restriction. I actually asked Matt personally yesterday and he said maybe, maybe in 2.4 maybe. So I'm looking forward to this, to summarize. You know, Rails method is still getting better and better so I want you all to play with these new features of method and we can all make this better, make method better to be more useful. So let's hack on method and make Ruby more fun. Thank you very much.