I have class Boy
that inherits class Person
, and includes module Bipedal
. Both Person
and Bipedal
have versions of #two_legs
.
module Bipedal
def two_legs(name)
puts "#{name} has exactly two limbs used for walking."
end
end
class Person
def two_legs(name)
puts "#{name} has two human legs."
end
end
class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
super(@name)
end
end
Since the Bipedal
module is included in Boy
, Bipedal#two_legs
takes precedence over the Person#two_legs
. When I call super
on a Boy
instance, the module Bipedal
takes precedence over the parent class Person
.
johnny = Boy.new('Johnny')
johnny.two_legs
# >> "Johnny has exactly two limbs used for walking."
I want to use one version in one place and the other in another. Bipedal
has other stuff, so I can't comment out include Bipedal
. Is there some standard way to let Boy#two_legs
or super
to use the parent class version instead of the module version as follows?
johnny.two_legs
# >> "Johnny has two human legs."
I came up with this:
Boy.superclass.instance_method(:two_legs).bind(self).call(@name)
which works in place of super(@name)
, but is more complicated than I was expecting.
Again, the question is, is there a standard way to force the parent class to take precedence over the module when calling super
?
One could use the method Method#super_method twice. That being a garden-variety Ruby method, I believe it would qualify as a "standard way" to let Boy#two_legs
invoke Person#two_legs
rather than Bipedal#two_legs
.
class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
method(:two_legs).super_method.super_method.call(@name)
end
end
willie = Boy.new('Willie')
willie.two_legs
Willie has two human legs.
Note the following.
willie.method(:two_legs).super_method.owner
#=> Bipedal
willie.method(:two_legs).super_method.super_method.owner
#=> Person