假设我有两个类:
Inner
有一个方法func
,可以为调用者提供值。Outer
有一个重写方法func
,它调用Inner.func
,对产生的值执行某些操作,然后将它们依次发送给自己的调用方。当我运行此示例代码时,Outer
中的块被跳过,我得到了这个奇怪的undefined method
错误:
# subclassed.rb
class Inner
def func
puts ' Inner entered func'
yield 1
yield 2
yield 3
puts ' Inner leaving func'
end
end
class Outer < Inner
def func
puts 'Outer entered func'
super.func do |value|
puts " Outer received #{value} !!! this never happens !!!"
yield value
end
puts 'Outer leaving func'
end
end
outer = Outer.new
outer.func do |value|
puts " Script received #{value}"
end
$ ruby subclassed.rb
Outer entered func
Inner entered func
Script received 1
Script received 2
Script received 3
Inner leaving func
C:/Source/temp/rubytest/subclassed.rb:14:in `func': undefined method `func' for nil:NilClass (NoMethodError)
from C:/Source/temp/rubytest/subclassed.rb:23:in `<main>'
但是,如果我使用封装,一切都按预期工作:
# encapsulated.rb
class Inner
def func
puts ' Inner entered func'
yield 1
yield 2
yield 3
puts ' Inner leaving func'
end
end
class Outer
def initialize
@inner = Inner.new # (use encapsulation)
end
def func
puts 'Outer entered func'
@inner.func do |value| # (use encapsulation)
puts " Outer received #{value}"
yield value
end
puts 'Outer leaving func'
end
end
outer = Outer.new
outer.func do |value|
puts " Script received #{value}"
end
$ ruby encapsulated.rb
Outer entered func
Inner entered func
Outer received 1
Script received 1
Outer received 2
Script received 2
Outer received 3
Script received 3
Inner leaving func
Outer leaving func
作为实验,我将def func
更改为def func(&callback)
,将yield 1
更改为callback.call(1)
,但我的行为相同。
有一些现有的帖子处理子类和超类,还有一些处理收益。但是,我无法找到有关此特定问题的任何内容。这是我第一次真正对Ruby在很长一段时间里所做的事情感到惊讶!有人有什么想法吗?
答案 0 :(得分:2)
class Outer < Inner
def func(&block)
puts "outer entered func"
super do |value|
puts " Outer received #{value}"
block.call(value)
end
puts "Outer leaving func"
end
end
我正在使用&block
传递块,然后在父方法的上下文中调用块。另外,只需使用super
代替super.func
来调用父方法。
<强>输出:强>
o = Outer.new
o.func do |val|
puts " Script received #{val}"
end
outer entered func
Inner entered func
Outer received 1
Script received 1
Outer received 2
Script received 2
Outer received 3
Script received 3
Inner leaving func
Outer leaving func