Extending Classes is a key part of Object Oriented Programming. It’s a central concept to frameworks in both PHP and Ruby. Take for instance a simple Laravel controller:
And Ruby on Rails:
class PagesController < ApplicationController def home render 'home' end end
It’s amazing how similar these 2 pieces of code are despite that under-the-hood the languages are so different.
Just from at a glance you can probably figure out that in Ruby speak the symbol
< is the PHP equivalent of
# in PHP terms, the PagesController _extends_ the ApplicationController class PagesController < ApplicationController # methods are defined in here... end
Extending Unexpected Classes in Ruby
No, from day to day use you can expect the same behavior from class extension in both PHP and Ruby.
The only difference being in Ruby that you can do some otherwise strange things like extending the
String class if you really feel the need to:
class Yarn < String def unravel puts 'Watch me unravel' end end yarn = Yarn.new('I am a ball of yarn') puts yarn => 'I am a ball of yarn' yarn.unravel => 'Watch me unravel'
In addition to extending any class you’d like, there’s a common practice in Ruby called Monkey Patching. Usually to overwrite functionality in a class, we’d have to extend the original class and override the public or protected method:
The other option is to use the Wrapper pattern and “wrap” the inside functionality. The big difference here is that we cannot override the wrapped classes function but we can extend it.
We can implement both of these patterns in Ruby, including the Wrapper pattern:
class Cat def meow puts 'meow' end end class HungryCat attr_accessor :cat initialize(cat) @cat = cat end def meow @cat.meow puts 'roarrrrr!' end end regular_cat = Cat.new hungry_cat = HungryCat.new(regular_cat) hungry_cat.meow => 'meow' => 'roarrrrr!'
But Ruby has one more trick up it’s dynamic wizard-like sleeve - Monkey Patching.
Monkey Patching is when you override a public method directly. It’s not a possiblity in static languages.
For example, Ruby on Rail’s Active Support has a monkey patch on the
Integer class to make life easier when needing to create dates:
# getting a date in the past is a cinch last_month = 1.month.ago # in the future is possible too in_a_few_weeks = 3.weeks.from_now
This is a result of Monkey Patching the
Integer class. Here’s a simplistic example:
class Integer def even? # self in this case is the actual digit self % 2 == 0 end def odd? self % 2 != 0 end end 2.even? => True 2.odd? => False
Now we have 2 convience methods for determining if a particular Integer is odd or even.
Great Power Requires Great Discipline
Ruby is known for letting you “cut with sharp knives” as a developer. These sharp knives are empowering, but they can also allow you to shoot your own foot.
Monkey Patching can hurt you in one distinct way:
Loss of Updates
When you Monkey Patch over top of another public method in a class that’s vendored - a.k.a. it’s part of a Gem - then you will not automatically receive the vendor’s updates to that Gem.
It’s up to you when to use Monkey Patching, and it does have it’s uses. Most of the time however it should not be your go to choice.