Any time that a Ruby class includes a module, that module is appended to that class’ hierarchy which has implications for its lookup order. Before Ruby 2.0 there was no elegant way of prepending that module without having to resort to hacks like
alias_method_chain where you would have ugly method names like
#original_without_addition. Now with Ruby 2.0 there is a neat solution to this.
Your class can now both prepend as well as include a module into its hierarchy without you having to explicitly do class evals. To help understand how it works, we summon the all-knowing Kanye to help us out:
class Kanye def announcement puts "I totes love Jay Z and Beyoncé" end end Kanye.new.announcement
We have a simple class with an
announcement method. When called, Kanye professes his love for his two idols.
I totes love Jay Z and Beyoncé
Now let’s imagine the very unlikely scenario wherein Kanye would be a bit rude. Instead of writing a whole new class from scratch, we can utilize Ruby’s amazing powers of inheritance and we’ll inherit from our original Kayne.
class RudeKanye < Kanye def announcement puts "Beyoncé had one of the best videos of all time!" super end end RudeKanye.new.announcement
Now when rude Kanye orates magnificently, the result will be:
Beyoncé had one of the best videos of all time! I totes love Jay Z and Beyoncé
He can express his opinions, and thanks to
super he can also express his invaluable original idea too. But what if Kayne had even more to say? I know, it’s highly unlikely, but because we can’t rule anything out, we’ll have to develop a solution for him. That solution is using Ruby’s
include methods. We create two modules with some more wisdom nuggets:
module RudeAnnouncementExtra def announcement puts "One of the best videos of all time!" super end end module RudeAnnouncementIntro def announcement puts "Yo, Taylor, I'm really happy for you, I'ma let you finish, but..." super end end
Then we add these modules into the
RudeKanye’s class using the following. Note that both methods are now public methods so you can simply call them like:
Now when rude Kanye makes an announcement:
The result is:
Yo, Taylor, I'm really happy for you, I'ma let you finish, but... Beyoncé had one of the best videos of all time! One of the best videos of all time! I totes love Jay Z and Beyoncé
Thanks to Ruby, people can have as many opinions as they want and we don’t have to duck punch our code to make that happen.