# The Duck Problem, or accessing one instance var from another

**URL:** <https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071>\
**Category:** Ruby\
**Created:** [January 24, 2006, 6:08pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071 "2006-01-24T18:08:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mourner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mourner](https://www.ruby-forum.com/u/mourner)\
**Post date:** [January 24, 2006, 6:08pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071/1 "2006-01-24T18:08:24Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![mourner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mourner](https://www.ruby-forum.com/u/mourner)\
**Post date:** [January 24, 2006, 6:11pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071/2 "2006-01-24T18:11:25Z")

</div>

On Mon, 23 Jan 2006, Vladimir A. wrote:

> me that it is not the most appropriate way of doing this. Or is it?  
> harp:~ \> cat a.rb  
> class Duck  
> attr\_accessor “quack\_behaviour”  
> def initialize(quack\_behaviour) self.quack\_behaviour =  
> quack\_behaviour::new(self) end  
> def quack() quack\_behaviour.quack end  
> def name() “duck” end  
> end  
> class QuackBehaviour  
> def self::duck\_attr a  
> module\_eval \<\<-code  
> def #{ a }() duck.#{ a } end  
> def #{ a }=(val) duck.#{ a }=val end  
> code  
> end  
> attr\_accessor “duck”  
> duck\_attr “name”  
> def initialize(duck) self.duck = duck end  
> def quack() p name end  
> end

duck = Duck::new(QuackBehaviour)  
duck.quack

harp:~ \> ruby a.rb  
“duck”

is one way. if you need to dynamically change the quack\_behaviour  
object i’d  
make a method that pushed/popped/ensured a QuackBehaviour object was in  
effect

- but having the QuackBehaviour object have a reference to their parent,  
if  
possible, simplifies things.

regards.

-a

---

<div class="post-metadata">

**Author:** ![mourner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mourner](https://www.ruby-forum.com/u/mourner)\
**Post date:** [January 24, 2006, 6:17pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071/3 "2006-01-24T18:17:30Z")

</div>

Vladimir A. wrote:

> 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?

Sounds like an application of state or strategy pattern. I posted some  
example code a few days / weeks ago. Basically, if your two classes are  
rather tightly coupled you can have each instance point to the other.  
That way both can access methods on the other instance. The only ugly  
thing being that you have to manually keep references in sync.

HTH

```
robert
```

---

<div class="post-metadata">

**Author:** ![mourner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mourner](https://www.ruby-forum.com/u/mourner)\
**Post date:** [January 24, 2006, 6:45pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071/4 "2006-01-24T18:45:02Z")

</div>

On 24/01/06, Vladimir A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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?

Huh?

class QuackBehaviour  
def loudly  
“LOUDLY”  
end  
end

class Duck  
def initialize  
@quack\_behaviour = QuackBehaviour.new  
@name = “Daffy”  
end

```
def quack
  @quack_behaviour.loudly
end

```

end

There’s nothing in the above that even remotely allows for  
QuackBehaviour#loudly to reach inside of the Duck instance. You will, as  
you said, need to either register the duck instance or pass +self+ as a  
parameter.

-austin

---

<div class="post-metadata">

**Author:** ![mourner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mourner](https://www.ruby-forum.com/u/mourner)\
**Post date:** [January 24, 2006, 6:51pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071/5 "2006-01-24T18:51:08Z")

</div>

Thanks! I will keep that in mind. Though I think that it complicates  
things a lot in exchange for using just “attr” instead of, say,  
“@obj.attr” for accessign an attribute.

---

<div class="post-metadata">

**Author:** ![mourner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mourner](https://www.ruby-forum.com/u/mourner)\
**Post date:** [January 24, 2006, 7:09pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071/6 "2006-01-24T19:09:17Z")

</div>

Thanks, Robert. You’re right, a strategy pattern (I just started  
reading “Head First Design Patterns” of O’Reilly). What do you mean by  
manually keep references synchronized?

I implented my solution with cross-references, and it seems quite  
automated (though there’s still room for improvement). Here’s what I  
came with (in short):

#================================================  
class Duck  
attr\_reader :name

def initialize(name, fly\_behaviour=:fly\_with\_wings,  
quack\_behaviour=:quack)  
@fly\_behaviour = FlyBehaviour.new(self, fly\_behaviour)  
@quack\_behaviour = QuackBehaviour.new(self, quack\_behaviour)  
@name = name  
end

def fly  
@fly\_behaviour.perform  
end

def quack  
@quack\_behaviour.perform  
end  
end

class Behaviour  
def initialize(object, behaviour);  
@obj = object;  
@behaviour = behaviour;  
end

def perform  
send(@behaviour)  
end

def self.list;  
self.protected\_instance\_methods  
end  
end

class FlyBehaviour \< Behaviour  
protected  
def fly\_with\_wings  
puts “#{@obj.name} is flying!”  
end

def do\_not\_fly  
puts “#{@obj.name} can’t fly. :-(”  
end  
end

class QuackBehaviour \< Behaviour  
protected  
def quack  
puts “#{@obj.name} is quacking! Quack!!”  
end

def squeak  
puts “#{@obj.name} is quacking! Squeak!!!”  
end  
end

class RubberDuck \< Duck  
def initialize(name)  
super(name,:do\_not\_fly,:squeak)  
end  
end

ducks = []  
ducks \<\< Duck.new(“George”)  
ducks \<\< RubberDuck.new(“Wacky”)

ducks.each do |duck|  
duck.quack  
duck.fly  
end

p QuackBehaviour.list  
#================================================

The next big thing would be to implement generating behaviour-related  
methods in the Duck class on the fly. Through method\_missing, maybe?  
And, of course, behaviour instance variables too. That seems a bit  
harder to do, but I’m a programming newbie after all! 🙂 The perfect  
use of the solution would look like:

usually\_able\_to :fly, :quack, :swim

that looks similiar to Rails has\_many and belongs\_too. Maybe I need to  
check it’s code for an idea.

And there’s another question: how to make all methods defined in  
Behaviour children protected? The code would be more attractive if I  
hadn’t to write “protected” in the beginning of each behaviour child.

---

<div class="post-metadata">

**Author:** ![mourner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mourner](https://www.ruby-forum.com/u/mourner)\
**Post date:** [January 24, 2006, 8:10pm UTC](https://www.ruby-forum.com/t/the-duck-problem-or-accessing-one-instance-var-from-another/53071/7 "2006-01-24T20:10:10Z")

</div>

Vladimir A. wrote:

> 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!
