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)