How the Ruby's super work in finding method?


#1

When one method defined in many places, I want to use the super to
invoke them one by one. This is the code:

#########################################
module M
def report( a = 4, b =5)
p “M report begin: a=#{a},b=#{b}”
a = 6
super(a)
p “M report end”
end
end

class B
def report(a=11,b=12)
p “B report 1 begin: a=#{a},b=#{b}”
p “B report 1 end”
end
def report(a=13,b=14)
p “B report 2 begin: a=#{a},b=#{b}”
#super()
p “B report 2 end”
end
end

class C < B
def report( a=8,b=9)
p “C report 1 begin: a=#{a},b=#{b}”
p “C report 1 end”
end
def report( a=7,b=3)
p “C report 2 begin: a =#{a},b=#{b}”
super()
p “C report 2 End”
end
include M
end

class D < C
def report( a = 2, b=1)
p “D report 1 begin: a=#{a},b=#{b}”
super(a,b)
p “D report 1 end”
end
include M
def report(a = -2, b=-1)
p “D report 2 begin: a=#{a},b=#{b}”
super
p “D report 2 end”
end
end

d = D.new
d.report

#########################################
That’s the output:

:!ruby testMethodGet.rb
“D report 2 begin: a=-2,b=-1”
“C report 2 begin: a =-2,b=-1”
“M report begin: a=4,b=5”
“B report 2 begin: a=6,b=14”
“B report 2 end”
“M report end”
“C report 2 End”
“D report 2 end”

I find sometimes it will invoke the super class’ method first(D->C->M),
but it will invoke the module’s method first(C->M->B) too.
I know I include the module in different place in the different classes.
But I don’t know the strange working .
Can anyone find the problem?


#2

On Nov 19, 9:23 pm, Qian J. removed_email_address@domain.invalid wrote:

end
p “B report 2 end”
super()
end

“C report 2 End”
“D report 2 end”

I find sometimes it will invoke the super class’ method first(D->C->M),
but it will invoke the module’s method first(C->M->B) too.
I know I include the module in different place in the different classes.
But I don’t know the strange working .
Can anyone find the problem?

First of all, you can’t define a method more than once. That is,
defining it a second time overwrites any previous definition, so if
you’re expecting to see B, C, or D report 1, that’s not going to
happen.

Second, once a module is part of the ancestor chain, re-including it
doesn’t do anything. You have B by itself, then C inherits from B, so
the lookup chain is

C -> B

Then C includes M

C -> M -> B

Then D inherits from C

D -> C -> M -> B

Then D includes M, but M is already present as an ancestor

D -> C -> M -> B


#3

Thanks for your help.
Now I know more about the module, super, class and the method finding.
The doesn’t describe detail.

Yossef M. wrote:

On Nov 19, 9:23�pm, Qian J. removed_email_address@domain.invalid wrote:
First of all, you can’t define a method more than once. That is,
defining it a second time overwrites any previous definition, so if
you’re expecting to see B, C, or D report 1, that’s not going to
happen.

Second, once a module is part of the ancestor chain, re-including it
doesn’t do anything. You have B by itself, then C inherits from B, so
the lookup chain is

C -> B

Then C includes M

C -> M -> B

Then D inherits from C

D -> C -> M -> B

Then D includes M, but M is already present as an ancestor

D -> C -> M -> B