ruby - 如何将块(成为 Proc 对象)传递给 ruby 方法
问题描述
我正在阅读有关 Ruby 的Pickaxe 书,并且遇到了以下示例:
class TaxCalculator
def initialize(name, &block)
@name, @block = name, block
end
def get_tax(amount)
"#@name on #{amount} = #{@block.call(amount)}"
end
end
tc = TaxCalculator.new ("Sales tax") {|amt| amt * 0.075 }
tc.get_tax(100) # => "Sales tax on 100 = 7.5"
tc.get_tax(250) # => "Sales tax on 250 = 18.75"
该示例的重点是说明,如果您在方法定义中的最后一个参数前面加上一个 & 符号,则任何关联的块都将被转换为 Proc 对象,并且该对象被分配给该参数。
现在,这一切都说得通,但我被一件事难住了:为什么需要在初始化方法中分配name
和block
到?@block
为什么需要name
?
对我来说,这似乎应该有效:
def initialize(name, &block)
@name, @block = block
end
但是,当我尝试在 irb 中@block
变为 nil 时,我得到一个错误,NoMethodError (undefined method "call" for nil:NilClass)
.
我不明白name
那个任务在做什么@block
。您希望将“销售税”传递给@name
. 但我看不到该街区如何使用“销售税”。
解决方案
赋值语法与块无关。相反,这里发生的事情称为“并行分配”。
这样,您可以通过一个原子操作从右侧的多个值中分配左侧的多个变量。从您的示例中,此语句
@name, @block = name, block
相当于
@name = name
@block = block
在这个例子中,这种用法更多的是一种噱头(我会在代码审查中标记)。但是,在某些模式中并行分配非常有用。
最重要的是能够切换两个变量的值而不需要中间变量:
a = 1
b = 2
a, b = b, a
另一种选择是将数组解构为多个变量的能力。在以下示例中,该方法返回一个数组,其元素被分配给两个变量hello
和world
。
def get_array
[:hello, :world]
end
hello, world = get_array
推荐阅读
- python - 加载图像后,我尝试运行音频文件
- sql - Delete or overwrite sql table and views from databricks
- python-3.x - 如果列值等于,如何将 csv 文件写入另一个 csv 文件?
- android - 我不能将 rn-nodeify 与 React-Native 一起使用 - 奇怪的 package.json 问题
- kotlin - 无法将双精度转换为格式字符串
- android - 如何从 Recyclerview.ViewHolder 调用后端
- regex - 使用 Impala regexp_like 查找十进制值
- javascript - 将滚动添加到 div 的末尾
- python - 3 轴图表所有组合
- python - 实现了似乎没有给出正确答案的 z 分数函数