Let’s say you have the following:
Announcement
You can find all my latest posts on medium.class Human def greeting puts "hello everybody" end end john = Human.new john.greeting
Next let’s say you want to add a new method, called “hungry”, then you can do this:
class Human def greeting puts "hello everybody" end def hungry puts "I am hungry" end end john = Human.new john.greeting
However another approach is as follows:
class Human def greeting puts "hello everybody" end end john = Human.new john.greeting # the following line will fail, because you called before defining the "hungry" method. # john.hungry class Human def hungry puts "I am hungry" end end john.hungry
Here we have extended the existing class with a new method. This was done by creating a follow up Human class block. This is possible because Ruby supports a concept known as “Open classes”, which lets you do exactly this, i.e. extend an existing class, without altering the original class-block.
“Monkey Patching” is something that’s made possible thanks to the concept of open classes. “Monkey Patching” is the term used to describing extending a class’s functionality (as shown above), or overwrite existing methods.
Monkey Patching is especially useful for modifying code from third party vendors.
Note if you wan to overwrite a private method, then the new method you have written needs to also be set top private.
class Human def greeting puts "hello everybody" end def hungry puts "I am hungry" end end john = Human.new john.greeting john.hungry class Human def hungry puts "I could eat a horse" end end john.hungry
This will output:
PS C:\Temp\irb> ruby .\openclasses.rb hello everybody I am hungry I could eat a horse PS C:\Temp\irb>
You can even use this approach to modify the behaviour of the classes that are in the standard library, such as the string class. For example:
puts "hello".size class String def size puts "goodbye" end end puts "hello".size
This outputs:
PS C:\Temp\irb> ruby .\overwritingstandardlibrary.rb 5 goodbye
Making changes in this way should be avoided because changing core functionality will confuse other people, and could stop othe ruby applications from working.