-3
module M
    def meth
        p "M"
    end
end

class C
    def meth
        p "C"
    end
end

class D < C
    #include M
end


d = D.new
p d.meth

Hi, can you please explain why the result of this code in Ruby is:

"C" 
"C"

(TWICE, as you can see)? Also, why uncommenting the line in class D definition renders "M", also TWICE?

This is about calling method x in a class which inherits from another class with method x and mixes in a module which also contains method x.

I can guess the double display of "M" in the second case is owed to the call d.meth: meth is found in the superclass of D and also in the module that D includes, so maybe the module method meth overwrites class C's method meth. And then, maybe both are executed.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
Sam
  • 3,067
  • 19
  • 53
  • 55

2 Answers2

3

The first "C" is printed by C#meth.

The second one is printed by p d.meth; The return value of the p "C" is "C" which is returned to the caller of the meth.

Just calling d.meth without p will print only once.

falsetru
  • 357,413
  • 63
  • 732
  • 636
3

The meth method within class C will print the value "C" as it currently stands, and next, since you are using another p statement at the end when you call p d.meth, the value "C" is printed again. The net effect is 2 print calls being made, causing the output of 2"C" statements.

To avoid this, just do

d = D.new
d.meth

The thing to note is that every method in ruby returns a value, so thats how "C" is available for printing the second time.

Every method in Ruby returns a value by default. This returned value will be the value of the last statement.

Same goes for the case when you use include M, the definition for method meth within module M already has a print statement with it, and the return value is printed again.

As for your guess, no you are wrong - it doesn't happen because the method is called twice. Ruby overwrites the earlier meth method inherited from "C" with the meth method of the the module. Check this for more on method overloading in ruby.

Community
  • 1
  • 1
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • Ruby doesn't return a value by default. It is what all methods do and as far as I know you can't change that. So it isn't 'default' it is just a characteristic of Ruby methods. – vgoff Nov 17 '13 at 21:09
  • @vgoff the text is quoted from the link I have used just above it. As for the `by default statement`, I think its a comparison on how other languages like python, C etc need an explicit return statement unlike ruby, which might not be what a newcomer to ruby would expect. – Anshul Goyal Nov 17 '13 at 21:15
  • @vgoff FWIW, I myself had gotten pretty confused when I saw return values being used without return statements when I was a beginner in ruby. – Anshul Goyal Nov 17 '13 at 21:21
  • It is good, just default carries some weight that it is meant to change given some condition. At least when I see the word 'default'. Had you been told while learning Ruby that it isn't default, that it is simply the characteristic of a method, perhaps there would have been no confusion. It was one of the first things I was told about Ruby. – vgoff Nov 17 '13 at 23:59
  • @vgoff I have learnt much of it on my own, and since I had a programming background in C/Python already, I was naive enough to assume a return was necessary :) – Anshul Goyal Nov 18 '13 at 00:02