Ruby 2.0 : Module#prepend
With a release date set to the 24th February 2013, the next major version of Ruby is around the corner. So what Ruby 2.0 will have to offer for its twentieth candle?
Like every new version of a language, this iteration will bring some performance improvements (yay, copy on write), and some new features.
Let's talk about a new method that will add a major change to the Ruby's model object, Module#prepend.
If you already clicked on that link, you can see that the documentation is not really up to date…
Ruby methods lookup
Consider this example :
module FooBar def hello puts 2 super end end class Foo def hello puts 'hello' end end class Bar < Foo include FooBar def hello puts 1 super end end Bar.new.hello
Ouputs the following:
1 2 "hello"
Bar class inherits from
Foo, and includes the module
FooBar. When the
hello is called on a instance of
Bar, the following is happening:
First, it outputs "1", then it calls the same method with super, but one step
above in the hierarchy, which is the module FooBar, prints 2, and calls super.
So, it looks in its own class, then in included modules, and then in class hierarchy.
Seems quite legit, but sometimes, you want a method from a module to take
the precedence on a method from the class. There are some solutions to accomplish
this task, like
alias_method_chain, but it's more a hack than anything - and
not really safe.
Module#prepend does exactly that. Now let's see how it works with a new example (Ruby 2.0 is needed for this one):
module FooBar def hello puts 2 super end end class Foo def hello puts 'hello' end end class Bar < Foo prepend FooBar def hello puts 1 super end end Bar.new.hello
This code example looks very much like the previous one, except that the module is prepended instead of included. Meaning that methods from these modules will have the precedence over the class.
But with a different output:
2 1 "hello"
Way safer and nicer that
alias_method_chain or some monkey patching.
Thanks to Module#prepend, a module for memorization or a cache over some orm
could be easily done. I'm pretty sure that
prepend will solve some problems in
a nice way; and looking forward to use it in a few months.
Coming next in this series: Module#refine.