Mixin technique overrides variables

Take a look at code bellow:

module Parent1
def initialize
@loc1 = 1
@loc2 = 2
end
end

class Parent2
def initialize
@loc3 = 3
@loc4 = 4
end

def displayp2
puts @loc3
puts @loc4
end
end

class Child < Parent2
include Parent1
def displayc
puts @loc1
puts @loc2
puts @loc3
puts @loc4
end
end

c = Child.new
c.displayc

I was thinking of something similar to multiple inheritance and my
expectaions was that all of local variables will be available in Child
class.
What I discovered that when you add
include Parent1
line to Child class @loc3 and @loc4 disappears.
When you comment this line @loc3 and @loc4 are available in Child class.

My question is why this work that way and how to get all of @loc
available in Child class?

It works this way because when you include Parent1, you give its
initialize
method to the Child class, so when you create a new instance of Child,
it
calls Child#initialize, which exists after the include and therefore
Parent2#initialize in the inheritance chain is never needed. Without the
include, Child#initialize ends up at Parent2#initialize via inheritance.

On Wed, Jan 5, 2011 at 6:10 AM, Konrad K. [email protected]
wrote:

module Parent1
def initialize
@loc1 = 1
@loc2 = 2
end
end

class Parent2
def initialize
@loc3 = 3
@loc4 = 4
end

def displayp2
puts @loc3
puts @loc4
end
end

class Child < Parent2
def displayc
puts @loc1
puts @loc2
puts @loc3
puts @loc4
end
end

You can see that when we ask the child for its initialize method,

it finds the one that Parent2 has defined, then when we include

Parent1,

it gets inserted before Parent2 in the inheritance chain,

and Child finds the one that Parent1 has defined.

c = Child.new
Child.ancestors # => [Child, Parent2, Object, Kernel, BasicObject]
c.method(:initialize) # => #<Method: Child(Parent2)#initialize>

class Child
include Parent1
end
Child.ancestors # => [Child, Parent1, Parent2, Object, Kernel,
BasicObject]
c.method(:initialize) # => #<Method: Child(Parent1)#initialize>

To get all the @loc, you can have the initialize method in Parent1

call
super,

which will find the next one in the chain.

note: super will forward any args that the method received,

so you don’t have to manually pass them on, unless you wish to change

them
Child.new.instance_variables # => [:@loc1, :@loc2]
module Parent1
def initialize
super
@loc1 = 1
@loc2 = 2
end
end
Child.new.instance_variables # => [:@loc3, :@loc4, :@loc1, :@loc2]

On Wed, Jan 5, 2011 at 2:27 PM, Konrad K. [email protected]
wrote:

You’re right, thanks for explanation :wink:

I decided to rename method in Parent1 from initialize to initializeP and
define initialize method in Child which calls super and initializeP, now
everything works fine.

IMHO this is a superior approach: define a method initialize for all
modules with signature (*a,&b) - this will integrate will every
inheritance chain and nicely play with all classes. So you can mix it
in into several different inheritance hierarchies.

module Parent1
def initialize(*a,&b)
super
@loc1 = 1
@loc2 = 2
end
end

module Parent2
def initialize(*a,&b)
super
@loc3 = 3
@loc4 = 4
end
end

class Child
include Parent1
end

p Child.new.instance_variables

class Child
include Parent2
end

p Child.new.instance_variables

class Child
def initialize
super
@loc5 = 5
end
end

p Child.new.instance_variables

Kind regards

robert

I have gone through the process of unsubscribing from this mailing
list numerous time to no avail. It is filling up my email box and I
want to discontinue receiving emails. The last time I did it, within
less than a minute, it told me that my request to get off the mailing
list had expired. If the ruby-lang site is written in Ruby, it doesn’t
give me much confidence that Ruby is right for what I need to do.

So…the answer remains…how do I unsubscribe?

–Peter

You’re right, thanks for explanation :wink:

I decided to rename method in Parent1 from initialize to initializeP and
define initialize method in Child which calls super and initializeP, now
everything works fine.

On Wed, Jan 5, 2011 at 10:42 AM, [email protected] wrote:

So…the answer remains…how do I unsubscribe?

–Peter

http://www.ruby-lang.org/en/community/mailing-lists/

Have you tried that one? There is a giant form at the bottom for
unsubscribing.

On Wed, Jan 5, 2011 at 6:01 PM, Josh C. [email protected] wrote:

On Wed, Jan 5, 2011 at 10:42 AM, [email protected] wrote:

http://www.ruby-lang.org/en/community/mailing-lists/

Have you tried that one? There is a giant form at the bottom for
unsubscribing.

And as large as the form is, teh “unsubscribe” option can hide itself
well. It’s in the “Action” drop down menu.


Phillip G.

Though the folk I have met,
(Ah, how soon!) they forget
When I’ve moved on to some other place,
There may be one or two,
When I’ve played and passed through,
Who’ll remember my song or my face.

Did that. Several times, in fact.

----- Original Message -----
From: “Phillip G.” [email protected]
To: “ruby-talk ML” [email protected]
Sent: Wednesday, January 5, 2011 12:20:33 PM
Subject: Re: This Email List

On Wed, Jan 5, 2011 at 6:01 PM, Josh C. [email protected] wrote:

On Wed, Jan 5, 2011 at 10:42 AM, [email protected] wrote:

http://www.ruby-lang.org/en/community/mailing-lists/

Have you tried that one? There is a giant form at the bottom for
unsubscribing.

And as large as the form is, teh “unsubscribe” option can hide itself
well. It’s in the “Action” drop down menu.


Phillip G.

Though the folk I have met,
(Ah, how soon!) they forget
When I’ve moved on to some other place,
There may be one or two,
When I’ve played and passed through,
Who’ll remember my song or my face.