mixin technique overrides variables

K

Konrad K.

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

Adam Prescott

[Note: parts of this message were removed to make it a legal post.]

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.
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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?
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 # => [:mad:loc1, :mad:loc2]
module Parent1
def initialize
super
@loc1 = 1
@loc2 = 2
end
end
Child.new.instance_variables # => [:mad:loc3, :mad:loc4, :mad:loc1, :mad:loc2]
 
K

Konrad K.

You're right, thanks for explanation ;)

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.
 
R

Robert Klemme

You're right, thanks for explanation ;)

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
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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



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

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

Phillip Gawlowski

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 Gawlowski

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top