Joel Drapper

Borrowing methods

Yesterday, we looked at how you can use bind_call on known UnboundMethod objects as a way to mitigate the risk that a default method has been overridden by a user.

Unbound methods also come in handy when you need to borrow a method definition from another module/class without inheriting from it.

If you’re working with a class that inherits directly from BasicObject, your class won’t have common Object methods like class. This is good if you’re trying to capture method_missing calls, but it can be really frustrating when you need one of the methods you’re used to.

In this case, you can use define_method but instead of passing a block, just pass it the UnboundMethod object from Object or whatever class has the method you need.

class MyObject < BasicObject
  define_method :class, ::Object.instance_method(:class)
end

You can even rename the method to something less likely to clash with your method_missing catcher.

class MyObject < BasicObject
  define_method :__class__, ::Object.instance_method(:class)
end

This trick is also useful if you need to borrow specific parts of a module without inheriting from it. For example, in Quickdraw the RSpec adapter borrows matcher methods directly from RSpec::Matchers without inheriting from it, since this module also defines methods we don’t want.

define_method :eq, ::RSpec::Matchers.instance_method(:eq)