如何为super
电话设置阻止为空?
class A
def foo
if block_given?
result = yield
# do stuff with the yield result
end
# some more code
end
end
class B < A
def foo
block_result = yield
# process block results and store it
# ...
super
end
end
B.new.foo { puts "block called" }
# => block called
# => block called
我不想两次屈服。是否有可能{class 1}}中的block_given?
返回false?
背景是我不拥有A
类,我不能改变它的A
方法,但我想避免两次调用我的块。我也不想将伪/空块传递给super,因为foo
的{{1}}方法的行为在给出块时会发生变化。
答案 0 :(得分:15)
实际上并不那么明显。从documentation我们知道:
super
传递所有参数super()
不传递参数文档没有说明这只适用于位置和关键字参数。 super()
仍然传递给定的块!
您必须通过调用:
显式取消设置块super(&nil)
您可能知道可以使用明确的block argument定义方法:
def foo(&block)
# ...
end
并且您可以将其作为块传递给另一个方法:(其他方法可能是super
)
def foo(&block)
super(&block)
end
现在,如果在调用方法时传递一个块,相应的block
变量将是Proc
的一个实例:
def foo(&block)
p block_given: block_given?, block: block
end
foo {}
#=> {:block_given=>true, :block=>#<Proc:0x00007ff4990d0030>}
如果你在没有通过阻止的情况下调用它,block
变量将只是nil
:
foo
#=> {:block_given=>false, :block=>nil}
因此,如果没有给出阻止,block
为nil
和
super(&block)
变为:
super(&nil)