Ruby 2 Methodology
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Matsuda, Akira
This talk focuses on "Method" in Ruby. Although Method is the key feature of an OOP language like Ruby, Ruby's Method is still drastically evolving. This session is a quick tour on new features and changes around Method in recent versions of the Ruby language. Not just introducing the APIs, we'll also show you lots of interesting stories behind these features, and real-world code examples. Through this session, you'll probably learn some modern methods of Ruby programming that you did never know.
 Let me start my talk titled Ruby 2 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 RubyConf this year has these session tracks, like domain patterns, less code, webware, Ruby, etc. And I think it's very well balanced, diverse topics. It's so like matured conference. But still, I'm so glad that RubyConf still has the Ruby in-depth track. By the way, I guess you've heard of another conference called RubyKaigi in Japan, which is happening next month. Yes? Thank you. Thank you. Who's coming to RubyKaigi? Raise your hands. Not so many, but yeah. Thank you. Thank you, guys. So the conference website looks like this. It has, 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 RubyKaigi. Everyone talks about Ruby because it's a Ruby conference. If you want to see more Ruby talks, I'm sure RubyKaigi is the conference you should go. 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 RubyKaigi maybe next year. And the conference is organized by these people and I'm at the very top as the chief organizer of RubyKaigi 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 going to talk about some modern usage of Ruby's method. I'm not just introducing these features like reference. I like to tell my own stories. I 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. 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 SFX 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. Then which character cannot be a method name? You can imagine some of these ASCII characters like one, two, three, or question mark, et sign, colon, semicolon. They might be invalid method name, for example, defining an et sign method. This causes a syntax error. So how can we define an et sign method without using C extensions? Actually do this a lot in my application. This is a real code example for my application. Defining et 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, et 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 et sign method can be called by send. And colonel send is actually not only used for calling these abnormal name method, but also for determining the method name 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 by a 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. And what's this? Yeah. You can call the private method 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, 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, so tarot. And Matt accepted this. It's okay. It's a merge. That's what he said. But I forgot to merge this in. 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. Right? So what exactly is protected? Who can explain? Who here can explain? Protected is like familiar in Java and C++. But Ruby is 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 use case in Rails. As you know, Rails includes so many protected. I saw more than 200 use cases, 200 occurrences 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. 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 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. However, again, this patch is still not merged. Because the patch has the problem. The Rdog problem. Rdog mutes private methods documentation. For example, if you have these methods and documentations, public, predicted, private, the Rdog generates documentations for public and protected. And does not generate documentation for private methods. So my Rails patch spoils so much documentations in Rails. It'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 Rdog problem in Rails. Consider we have this class. Like public, protected, private. This is introduced, I guess, 2.1. So generating Rdog 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, Rdog, Rdog. So we need a patch. Once 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. And 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 a type error. So you cannot unbind a method from 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. It's kind of cherry picking a method without including the whole module. And more new features in Ruby 2.2 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. 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. So how can we know what kind of method does a method, I'm sorry, parameter does a method take? Ruby 1.9 has method, parameters method implemented by this guy, Koichi. He's of course, you know, you know who they are all. He's the author of Ruby 1.9 VM called VARV, 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 going to show you a real world example of using this method parameters. Say Rails plugin written by me. And it's kind of something to make your Rails controller like Merv's 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. 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 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 can he fix it this? We introduced a new feature called binding.local variables. And binding.local variables get. And now you can access the if variable this way. All 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, the support will be 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. I mean, 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. The next topic is module prepend. 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.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. 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 doesn't always act as it really means. What if we have another chain like callback? Now the save method does save callback and validation and save. And let's call the save without validation method. It's not only skipping the validation, but it also skips the callback. So it's such harmful. Save without validation doesn't only skip validation in some cases. And you cannot tell which case. 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 reverse or the module includes. Module included 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. This is the real-world example of using module prepend. All of these used to be alias method chains. So there used to be tons of method definition. But using prepend, it just looks like the only method defined here is render. And yes, very simple, very clean. The module prepend always comes with send. I mean like this. Send prepend. And 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 Mets. 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 how it's 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 this 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 Ailius method chain. I said there's no way calling save without validation because there's no save without validation method defined in module prepend. 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 prepend. So what if we have two modules prepended like this, validation callback? You can call super method super method and still you can call save only. 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. So you can iterate the super method until the owner returns the target class. And to generalize this a little bit, you can monkey patch method object like this called without validation. You can call without validation using this method. So you can still something like Ailius 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, unbug 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, super method, it should return nil but it loops between the class and module. So it's another bug. This should be fixed I guess hopefully before 2.3. I guess I have five more minutes to talk about refinements. So module prepend is a great tool to monkey patch. It's less polluting than Ailius. 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 proof we can use refinements. Refinements is introduced from Ruby 2.0 by Sugao San who is Matt's boss. 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 it's, you know, 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. Actually asked Matt personally yesterday and he said maybe, maybe in 2.4 maybe. So I'm looking forward to this. All right. To summarize. Ruby's 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. Thank you.
 Let me start my talk titled Ruby 2 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 RubyConf this year has these session tracks, like domain patterns, less  code, webware, Ruby, etc.  And I think it's very well balanced, diverse topics.  It's so like matured conference.  But still, I'm so glad that RubyConf still has the Ruby in-depth track.  By the way, I guess you've heard of another conference called RubyKaigi in Japan, which  is happening next month.  Yes?  Thank you.  Thank you.  Who's coming to RubyKaigi?  Raise your hands.  Not so many, but yeah.  Thank you.  Thank you, guys.  So the conference website looks like this.  It has, 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 RubyKaigi.  Everyone talks about Ruby because it's a Ruby conference.  If you want to see more Ruby talks, I'm sure RubyKaigi is the conference you should go.  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 RubyKaigi maybe next year.  And the conference is organized by these people and I'm at the very top as the chief organizer  of RubyKaigi 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 going to talk about some modern usage of Ruby's method.  I'm not just introducing these features like reference.  I like to tell my own stories.  I 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.  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 SFX 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.  Then which character cannot be a method name?  You can imagine some of these ASCII characters like one, two, three, or question mark, et  sign, colon, semicolon.  They might be invalid method name, for example, defining an et sign method.  This causes a syntax error.  So how can we define an et sign method without using C extensions?  Actually do this a lot in my application.  This is a real code example for my application.  Defining et 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, et 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 et sign method can be called by send.  And colonel send is actually not only used for calling these abnormal name method, but  also for determining the method name 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 by a 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.  And what's this?  Yeah.  You can call the private method 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, 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, so tarot.  And Matt accepted this.  It's okay.  It's a merge.  That's what he said.  But I forgot to merge this in.  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.  Right?  So what exactly is protected?  Who can explain?  Who here can explain?  Protected is like familiar in Java and C++.  But Ruby is 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 use case in Rails.  As you know, Rails includes so many protected.  I saw more than 200 use cases, 200 occurrences 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.  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 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.  However, again, this patch is still not merged.  Because the patch has the problem.  The Rdog problem.  Rdog mutes private methods documentation.  For example, if you have these methods and documentations, public, predicted, private,  the Rdog generates documentations for public and protected.  And does not generate documentation for private methods.  So my Rails patch spoils so much documentations in Rails.  It'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 Rdog problem in Rails.  Consider we have this class.  Like public, protected, private.  This is introduced, I guess, 2.1.  So generating Rdog 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, Rdog, Rdog.  So we need a patch.  Once 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.  And 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 a type error.  So you cannot unbind a method from 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.  It's kind of cherry picking a method without including the whole module.  And more new features in Ruby 2.2 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.  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.  So how can we know what kind of method does a method, I'm sorry, parameter does a method  take?  Ruby 1.9 has method, parameters method implemented by this guy, Koichi.  He's of course, you know, you know who they are all.  He's the author of Ruby 1.9 VM called VARV, 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 going to show you a real world example of using this method parameters.  Say Rails plugin written by me.  And it's kind of something to make your Rails controller like Merv's 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.  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 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 can he fix it this?  We introduced a new feature called binding.local variables.  And binding.local variables get.  And now you can access the if variable this way.  All 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, the support will be 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.  I mean, 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.  The next topic is module prepend.  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.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.  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 doesn't always act as it really means.  What if we have another chain like callback?  Now the save method does save callback and validation and save.  And let's call the save without validation method.  It's not only skipping the validation, but it also skips the callback.  So it's such harmful.  Save without validation doesn't only skip validation in some cases.  And you cannot tell which case.  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 reverse or the module includes.  Module included 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.  This is the real-world example of using module prepend.  All of these used to be alias method chains.  So there used to be tons of method definition.  But using prepend, it just looks like the only method defined here is render.  And yes, very simple, very clean.  The module prepend always comes with send.  I mean like this.  Send prepend.  And 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  Mets.  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 how it's 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 this 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 Ailius method chain.  I said there's no way calling save without validation because there's no save without  validation method defined in module prepend.  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 prepend.  So what if we have two modules prepended like this, validation callback?  You can call super method super method and still you can call save only.  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.  So you can iterate the super method until the owner returns the target class.  And to generalize this a little bit, you can monkey patch method object like this called  without validation.  You can call without validation using this method.  So you can still something like Ailius 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, unbug 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, super method, it should return nil but it loops  between the class and module.  So it's another bug.  This should be fixed I guess hopefully before 2.3.  I guess I have five more minutes to talk about refinements.  So module prepend is a great tool to monkey patch.  It's less polluting than Ailius.  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 proof we can use refinements.  Refinements is introduced from Ruby 2.0 by Sugao San who is Matt's boss.  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 it's, you know, 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.  Actually asked Matt personally yesterday and he said maybe, maybe in 2.4 maybe.  So I'm looking forward to this.  All right.  To summarize.  Ruby's 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.  Thank you.
Ruby_2_Methodology_0_71.png Ruby_2_Methodology_72_263.png Ruby_2_Methodology_264_6743.png Ruby_2_Methodology_6744_8363.png Ruby_2_Methodology_8364_9299.png Ruby_2_Methodology_9300_9467.png Ruby_2_Methodology_9468_10955.png Ruby_2_Methodology_10956_11363.png Ruby_2_Methodology_11364_12407.png Ruby_2_Methodology_12408_20243.png Ruby_2_Methodology_20244_22739.png Ruby_2_Methodology_22740_22895.png Ruby_2_Methodology_22896_22943.png Ruby_2_Methodology_22944_23171.png Ruby_2_Methodology_23172_24155.png Ruby_2_Methodology_24156_25283.png Ruby_2_Methodology_25284_30959.png Ruby_2_Methodology_30960_31475.png Ruby_2_Methodology_31476_33419.png Ruby_2_Methodology_33420_35687.png Ruby_2_Methodology_35688_36719.png Ruby_2_Methodology_36720_37055.png Ruby_2_Methodology_37056_42455.png Ruby_2_Methodology_42456_43511.png Ruby_2_Methodology_43512_45035.png Ruby_2_Methodology_45036_45359.png Ruby_2_Methodology_45360_46079.png Ruby_2_Methodology_46080_46211.png Ruby_2_Methodology_46212_46775.png Ruby_2_Methodology_46776_49343.png Ruby_2_Methodology_49344_50783.png Ruby_2_Methodology_50784_51839.png Ruby_2_Methodology_51840_52691.png Ruby_2_Methodology_52692_53759.png Ruby_2_Methodology_53760_54431.png Ruby_2_Methodology_54432_57395.png Ruby_2_Methodology_57396_62111.png Ruby_2_Methodology_62112_62159.png Ruby_2_Methodology_62160_62458.png