How to Delegate Method Call to Another Object in Ruby
There is a way of delegating of an object’s method call to a different object in Ruby. In other word, we can make one object capable of impersonating another. We can accomplish this with the use of delegate library.
Delegate library helps to generate custom classes which in turn can impersonate objects of any other class. These newly defined classes respond to all method of the classes they are impersonating. This is the only thing that these classes do.
In order to set this up, we need to include “delegate” library
require ‘delegate’
class MyFixnum < DelegateClass(Fixnum)
def to_s
delegate_s = __getobj_ _.to_s
check = abs
case check % 10
when 1 then suffix = “st”
when 2 then suffix = “nd”
else suffix = “th”
end
return delegate_s + suffix
end
end
We just created new class MyFixnum which has all the methods of Fixnum class. In addition, it defined its own to_s method which we defined as an override to existing Fixnum class metho to_s. This approach is commonly used when you don’t have direct access to a class and want to extend the behavior of its objects. This is important to use when original class cannot be modified at all.
There are several exceptions with the Ruby Delegates. You cannot override such methods as is_a?
Another interesting aspect in Ruby delegation is Forwardable delegate. It is designed to delegate any of an objects methods to another object.
Example of this Forwardable module is presented below.
class MyCustomArray
extend Forwardable
def initialize
@array = []
end
def_delegator :@array, :<<
end
This custom class will only allow array with append functionality but no other types of methods. For example, calling on the size of an array will produce “undefined method ‘size’ for the array”
Both delegates work just fine, but if you really want to create your own class with restrictions for any existing class, Forwardable approach will work the best.