rubyoopinheritance

Class and inheritance


I'm trying to understand the inheritance system in Ruby. This is my code :

class Man
  attr_accessor :name

  def initialize(name = "Foo")
    @name = name
  end
end

class User < Man
  attr_accessor :mail

  def initialize(mail = "bar")
    super
    @mail = mail
  end
end

And this is my test :

man = Man.new
man
=> #<Man:0x007fb68da4a768 @name="Foo">

user = User.new
user
=> #<User:0x007fb68da442c8 @name="bar", @mail="bar">

I don't understand why user's @name isn't "Foo" ! Normaly, it should because it's the default argument in the man's initialize method, no ?

Thanks for your help !


Solution

  • super (without an argument list) calls the same method in the superclass with the same arguments that were passed in. If you want to explicitly pass no arguments, you must use an empty argument list: super().

    Remember: super is not a method call, it's a keyword and keywords don't have to follow the normal method call evaluation rules. This is one of those differences. For a method call, foo and foo() are equivalent, they both pass no arguments. For super, there is a difference: super() passes no arguments, super forwards the arguments.

    Now, here's an additional twist: actually, you don't pass any arguments to initialize, so how are they getting passed on … or do you? Well, it turns out, for the purposes of calling super, default arguments to optional parameters are treated as if they had been passed explicitly.