我对以下内容感到满意:
def some_def(foo, &block)
puts "block utilized below"
block.call(foo)
end
def some_other_def(bar)
puts "using yield below"
yield bar
puts "and back into the method"
end
所以我学会了将块(和procs)与yield
关键字分开。
但是,我遇到了以下代码:
# ./open_file.rb
class File
def self.open(name, mode, &block)
file = new(name, mode)
return file unless block_given?
yield(file)
ensure
file.close
end
end
当我在irb中实现执行这段代码时,似乎参数&block
并不重要:
irb -r ./file.open.rb
做一些类似的事情:
File.open('foo.txt','r') {|f| puts f}
&block
是否由block_given?
呈现为可选:
return file unless block_given?
2条答案
按热度按时间sqyvllje1#
一般来说,只有在需要将块传递给另一个方法时才使用
&block
参数,例如在这个虚构的例子中:或者来自Rails的
Enumerable#sum
的真实的版本:在这两种情况下,调用方法的块与另一个方法调用一起使用,因此您需要一种方法来引用该块(即名称)。
所以
block_given?
/yield
和&block
服务于不同的目的。能够调用block_given?
并不意味着&block
是多余的,而且,就像上面的#sum
实现一样,它们甚至可以一起使用。31moq8wy2#
方法签名中的
&block
接受一个块,将其转换为proc,并将其分配给名为block
的变量。如果没有提供块,则将block
分配给nil
。是否在方法定义中使用参数
block
并不重要,就像在下面的定义中是否使用普通方法参数bar
并不重要一样:然而,接受一个块作为参数而不使用它是多余的,也是浪费资源的。向其他程序员显式指示该方法接受一个块可能仍然有意义。
使用
block_given?
与所有这些都无关。它与是否通过&
接受一个块作为参数无关。它直接引用该块,而不考虑block
。