我有一些类似于以下内容的东西:
class A
def foo
bar
end
def bar
puts "A"
end
end
class B < A
def foo
super
end
def bar
puts "B"
end
end
所需的输出将能够调用B.new.foo #=> "A"
。一旦调用super,是否有可能将范围限制到父级?这对我来说有点不对劲,所以也许这表明设计不好,但是我很好奇这是否可能。
答案 0 :(得分:2)
这里的问题是B
定义了一个新的bar
方法,该方法取代了A
中定义的方法。如果您需要保留原有行为,则必须 为此创建一个别名:
class A
def foo
original_bar
end
def bar
puts "A"
end
alias_method :original_bar, :bar
end
class B < A
def foo
super
end
def bar
puts "B"
end
end
在此处使用alias_method
保留了子类未覆盖的原始方法的“副本”。
不过,您是对的,这有点混乱。您可能需要将bar
声明为private
,以免轻易被推翻。
答案 1 :(得分:1)
这是另一种方法,我仅出于教育目的而提出。
class A
def foo
m = method(:bar)
m = m.super_method until m.owner == A
m.call
end
def bar
puts "A"
end
end
class B < A
def foo
super
end
def bar
puts "B"
end
end
class C < B
def foo
super
end
def bar
puts "C"
end
end
B.new.foo
A
C.new.foo
A
A.new.foo
A
答案 2 :(得分:1)
这是另一种方式。
您通过以下方式获得A
的(未绑定)实例方法bar
:
um = A.instance_method(:bar)
#=> #<UnboundMethod: A#bar>
此方法可以通过以下方式绑定到当前接收者:
bm = um.bind(self)
#=> #<Method: A#bar>
然后可以调用绑定方法:
bm.call
# "A"
在您的代码中:
class A
def foo
A.instance_method(:bar).bind(self).call
end
# ...
end