Monkey-patching Ruby constructors

It's frowned upon, I know. But monkey-patching allows methods to be replaced with new ones that can still call the old ones. I needed to add some code to a constructor for a class whose source I didn't control. Subclassing was inappropriate, so the monkey-patch was the way to go.

! this is a note to self and may include errors or other misinformation.

Version 2 of Ruby introduced prepend which allows a module to be used to monkey-patch a class. It works like this:

module MonkeyPatch
  def initialize(*args)
    super
  end
end

Of course, additional code goes inside initialize and can go either side of the call to super. The patch is then applied like this:

class SomeClass
  prepend MonkeyPatch
end

Prior to the introduction of prepend, things were more difficult.

class SomeClass
  class << self
    alias_method :__new__, :new
    def new(*args)
      __new__(*args)
    end
  end
end

The original constructor is still accessible because alias_method gave it a new name __new__. This effect can be removed with a slightly different approach:

class SomeClass
  class << self
    __new__ = instance_method(:new)
    def new(*args)
      __new__.bind(self).(*args)
    end
  end
end

Or, an alternative with define_method:

class SomeClass
  class << self
    __new__ = instance_method(:new)
    define_method(:new) do |*args|
      __new__.bind(self).(*args)
    end
  end
end

Note the __new__ returned by instance_method is an unbound method assigned to a local variable so it's visible only within this code block. To call it, it needs to be re-bound to the object: self.

Note these latter examples patch new instead of initialise. This is because patching the latter doesn't work (actually, neither did patching new - but prepend works perfectly).

Read more here, here and here