ruby - `block_given?` 是否呈现 `&block` 参数可选?
问题描述
我对以下内容感到满意:
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
所以我学会了将块(和过程)与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
由 in 呈现为可选block_given?
:
return file unless block_given?
解决方案
通常,仅当您需要将块传递给另一个方法时才使用该&block
参数,例如在此示例中:
def m(&block)
some_array.map(&block)
end
Enumerable#sum
或者这个来自 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
实现中,它们甚至可以一起使用。
推荐阅读
- python-3.x - 通过分隔获取列表中每个单词的计数
- linux - 使用“set -e”命令重用 bash 错误处理“陷阱”逻辑无法正确调用错误处理函数
- json - 如何在 Redis 中使用 cmsgpack 和 Lua 存储具有空值的 JSON?
- php - WooCommerce wc_get_product 返回 False?
- reactjs - 使用 React Js 在按钮单击的同一页面中附加数据
- flutter - Flutter Listview.builder - 将具有特定子项的列表构建到 ROW 中
- python - Cython 的 pyx 文件能否只占用标头定义的一小部分
- docker - Google Cloud Platform - 实例停止后删除 AI Notebook
- javascript - 如何处理二维多边形轮廓的自相交
- vhdl - 将地图移植到多个实体的最佳方式