Thufir wrote:
On Sun, 18 Nov 2007 06:20:04 +0900, Raul P. wrote:
- Thufir was right …
Well that’s very complimentary of you
Just stating a fact in the summary I attempted to do (which does not
include the interesting and alternative view given by Trans, which came
after).
I need to learn more about Delegation…
You can learn what Delegation is very easily; the real work in the
Forwarding module is done in a few lines; I wrote a mini-version of the
module removing exception processing and others things not necessary, to
play with it a bit.
Look at this simplified version (used in the example below):
module Simple_Forwardable
def def_delegator(accessor, method, ali = method)
module_eval(<<-EOS)
def #{ali}(*args, &block)
#{accessor}.send(:#{method}, *args, &block)
EOS
end
end
Believe it or not, these 6 lines are the heart of Forwardable; in short,
in case you are not familiar with some things:
a) the method ‘send’ is used to ‘send’ a method name (eg, a method that
you have in a string or symbol, for example that you collected from a
web form or cmd line) to an object.
b) the module_eval allows to define dynamically methods using
interpolation.
That’s it!
If the syntax looks a bit mysterious at first, look at ‘accessor’ as our
@engine object and ‘method’ as ‘vroom’. Notice that we can even name an
alias for ‘vroom’ if in the Vehicle class we prefer a different name
(say, ‘rev’); and,we can even pass arguments (eg, we can pass the level
of the vroom we want). Both are done in the file below.
Below is the file that you may want to play with, if you find it useful
(it combines the 2 examples given by Liam in one file; perhaps there are
too many options, but you will decide that).
Good luck! and perhaps let us know how your project goes and if stood up
well to the shock with ‘reality’
Raul
module Simple_Forwardable
def def_delegator(accessor, method, ali= method)
module_eval(<<-EOS)
def #{ali}(*args, &block)
#{accessor}.send(:#{method}, *args, &block)
end
EOS
end
end
from Liam’s examples, combined
class Engine
def vroom(level)
puts “vroom #{level}”
end
end
class MustangEngine
def vroom(level)
puts “rumble #{level}”
end
end
class Vehicle
extend Simple_Forwardable
def_delegator :@engine, :vroom, :rev
attr_accessor :engine
def initialize(engine)
@engine=engine
end
end
class Factory
def self.build_car
Vehicle.new(Engine.new)
end
end
falcon = Factory.build_car
falcon.rev(‘mid’) # => vroom mid
v = Vehicle.new(Engine.new)
v.rev(‘high’) # => vroom high
changing the engine
v.engine = MustangEngine.new
v.rev(‘low’) # => rumble low