我对以下内容感到满意:
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}
Qazxswpoi是否可选&block
:
block_given?
通常,如果需要将块传递给另一个方法(例如在此示例中),则只使用return file unless block_given?
参数:
&block
或者这个真实版本的def m(&block)
some_array.map(&block)
end
:
Enumerable#sum
from Rails
在任何一种情况下,调用该方法的块都与另一个方法调用一起使用,因此您需要一种方法来引用该块(即名称)。
所以def sum(identity = nil, &block)
if block_given?
map(&block).sum(identity)
else
sum = identity ? inject(identity, :+) : inject(:+)
sum || identity || 0
end
end
/ block_given?
和yield
有不同的用途。能够调用&block
不会使block_given?
多余,并且,如上面的&block
实现,它们甚至可以一起使用。
方法签名中的#sum
接受一个块,将其转换为proc,并将其分配给名为&block
的变量。如果没有提供块,则block
被指定为block
。
是否在方法定义中使用参数nil
并不重要,就像在以下定义中是否使用普通方法参数block
无关紧要:
bar
但是,接受块作为参数而不使用它是多余的并且浪费资源。对于程序员明确指出该方法接受块可能仍然有意义。
使用def foo(bar); end
与所有这些无关。它与块是否已被block_given?
作为参数接受无关。无论&
如何,它都直接指向块。