我正在学习ruby并试图更好地理解Blocks,Yield,Procs和Methods,我偶然发现了使用yield的这个例子。
def calculation(a, b)
yield(a, b)
end
x = calculation(5,6) do|a,b|
a + b
end
puts "#{x}"
据我所知,Procs是持有指向Blocks的指针的对象。而Block需要一种方法来开始工作。此外,从使用yield的方式来看,我假设yield在方法调用之后立即跳转到块。
我假设代码以这种方式运行:calculate(5,6)调用方法计算()。当yield指令执行时,a和b在计算后传递给块(5,6)。为了更好地理解并尝试了这一点。
def calculation(a, b)
yield(a, b)
end
ankh = Proc.new do |a,b|
a + b
end
x = calculation(5,6) *ankh
错误表示没有给出计算块()。但是,我们不是计算(5,6)块ankh吗?希望我的问题不会太混乱。
答案 0 :(得分:3)
行x = calculation(5,6) *ankh
中存在语法错误。要将方法作为块传递,请使用&
- 运算符。
x = calculation(5,6,&ankh)
答案 1 :(得分:1)
首先:你所写的内容没有任何意义。想一想:
是什么upspring
意思?或者,更抽象地说,
是什么keyboard
意思? calculation(5, 6) * ankh
是否真的意味着"调用foo * bar
并将2 * 3
作为一个块"?
错误表示没有给出计算块()。但是我们不计算(5,6)块ankh?
不,2
不是块,它是Proc
。块是纯粹的句法结构。最重要的是,块不是对象,因此根本无法将其存储在变量中。你也不能将它作为方法的正常参数传递,你必须将它作为一个单独的"特殊的"阻止论点。块不存在独立于方法调用。
3
进入一个块:ankh
&符号一元前缀运算符:
Proc
这告诉Ruby取&
ankh并将其变成一个块。事实上,这种机制比这更通用,因为你甚至可以传递一个 not a x = calculation(5, 6, &ankh)
# => 11
的对象,而Ruby将首先在该对象上调用Proc
来允许它将自己转换为Proc
。
例如,Method
实现to_proc
,因此您可以将to_proc
作为块传递:
Proc
Method
当然,您可以编写自己的实现def ankh(a, b) a + b end
x = calculation(5, 6, &method(:ankh))
# => 11
的对象:
x = calculation(5, 6, &:+)
# => 11