Consider this class
class Duck
attr_accessor :name
def initialize(name)
@name = name || 'Donald'
end
# Some quacking methods..
def to_s
"#{@name} (Duck)"
end
end
I would like my duck to respond to methods like upcase, sub, gsub, etc.., so I can do
my_duck = Duck.new("Scrooge")
my_duck.upcase
--> "SCROOGE (DUCK)"
Besides manually implementing these methods, is there a nifty way I can pick out String methods that are not self-mutating and automatically have my class respond to those, then call to_s and then call the method on the resulting string?
You could use the Forwardable module:
require 'forwardable'
class Duck
extend Forwardable
# This defines Duck#upcase and Duck#sub, you can
# add as many methods as you like.
def_delegators(:to_s, :upcase, :sub)
# All the other code here...
end
Duck.new('duffy').upcase
# => DUFFY (DUCK)
Duck.new('rubber').respond_to?(:upcase)
# => true
In general calling def_delegators(:foo, :bar) is equivalent to define the bar method by hand like this:
def bar(*args, &block)
foo.bar(*args, &block)
end
The first argument to def_delegators can be the name of an instance variable, i.e. def_delegators(:@foo, :bar, :baz).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With