From: Joel VanderWerf Date: 2006-01-25T04:04:03+09:00 Subject: Re: [newbie] The Duck Problem, or accessing one instance var from another Vladimir Agafonkin wrote: > Hi! > > What is the best way to access class' instance variables from a method > of another instance variable of the same class that is a class itself? > :-) > > OK, Let's say I have Duck class with an instance variable > @quack_behaviour of QuackBehaviour class inside. Duck#quack method > calls one of the QuackBehaviour methods, and I want to access some of > the intance variables (say, @name) of the caller Duck object from that > method. > > One way is to set an attr_accessor :name (or use instance_variable_get) > and pass "self" as a parameter to the @quack_behaviour method. But it > seems for me that it is not the most appropriate way of doing this. Or > is it? This is a slightly different way, based on a soon-to-be-released version of MinDI (which is a dependency injection framework and hence the "inject" terminology): module Injectable module Injected def method_missing(*args, &block) @__injectable__container__ || super @__injectable__container__.send(*args, &block) rescue NoInjectedMethodError super end end def inject_into obj obj.extend Injected obj.instance_variable_set(:@__injectable__container__, self) obj end def method_missing(m, *rest) raise NoInjectedMethodError end end class Duck include Injectable def quack; @quack_behavior.quack; end def waddle; @waddle_behavior.waddle; end def initialize(h) @quack_behavior = h[:quack_behavior] @waddle_behavior = h[:waddle_behavior] inject_into @quack_behavior inject_into @waddle_behavior end end class StandardQuacker def quack puts "QUACK!" end end class NoisyWaddler def waddle quack # note that this propagates to Duck then to quacker puts "" quack end end duck = Duck.new( :quack_behavior => StandardQuacker.new, :waddle_behavior => NoisyWaddler.new ) duck.waddle __END__ Output: QUACK! QUACK! -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407