Reputation: 5916
Is there a way in Ruby (2.5) to call a method defined in an included module in the same way super
works for inheritance?
I mean, supposing I have the following
class Parent
def name
"parent"
end
end
class Child < Parent
def name
"my parent is #{super}"
end
end
When I call Child.new.name
, I get my parent is parent
.
How can I achieve the same in the following situation?
module Parent
def name
"parent"
end
end
class Child
include Parent
def name
"my parent is #{???}"
end
end
What should I replace ???
with?
Thank you
Upvotes: 1
Views: 344
Reputation: 110665
We are given the module Parent
:
module Parent
def name
"parent"
end
end
and the class Child
:
class Child
include Parent
def name
"my parent is #{super}"
end
end
As @Tai points out, we can use super
to obtain:
Child.new.name
#=> "my parent is parent"
because
Child.ancestors
#=> [Child, Parent, Object, Kernel, BasicObject]
In what sense is the module Parent
the "parent" of the class Child
? Yes, those are just words, but it is misleading.
Now let's create another module and have Child
include it.
module A
def name
"A"
end
end
Child.include A
Child.new.name
#=> "my parent is A"
because
Child.ancestors
#=> [Child, A, Parent, Object, Kernel, BasicObject]
We see that it would been clearer to define Class#name
as follows:
def name
"the last module included is #{super}"
end
Let's try one more thing: using Module#prepend.
module B
def name
"B"
end
end
Child.prepend B
Child.new.name
#=> "B"
not "my parent is B", because
Child.ancestors
#=> [B, Child, A, Parent, Object, Kernel, BasicObject]
meaning that B#name
(which does not call super
) was executed (not Child#name
). This means the results are meaningless if any modules have been prepended.
Upvotes: 2
Reputation: 1254
You can still use super
:
module Parent
def name
"parent"
end
end
class Child
include Parent
def name
"my parent is #{super}"
end
end
Child.new.name # => "my parent is parent"
When including a module, ruby will add this module to inheritance chain.
Child.ancestors # => [Child, Parent, Object, Kernel, BasicObject]
Thus, calling super
in Child
will call the corresponding methods in its ancestors.
Upvotes: 6