为什么这个块在存储在proc中时不会运行?

时间:2016-06-24 06:01:35

标签: ruby

我正在学习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吗?希望我的问题不会太混乱。

2 个答案:

答案 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。块是纯粹的句法结构。最重要的是,块不是对象,因此根本无法将其存储在变量中。你也不能将它作为方法的正常参数传递,你必须将它作为一个单独的"特殊的"阻止论点。块不存在独立于方法调用。

然而, 是一种"转换" a 3进入一个块:ankh&符号一元前缀运算符:

Proc

这告诉Ruby取& ankh并将其变成一个块。事实上,这种机制比这更通用,因为你甚至可以传递一个 not a x = calculation(5, 6, &ankh) # => 11 的对象,而Ruby将首先在该对象上调用Proc来允许它将自己转换为Proc

例如,Method实现to_proc,因此您可以将to_proc作为块传递:

Proc

此外,Symbol实施to_proc

Method

最后,Hash也实现了to_proc

当然,您可以编写自己的实现def ankh(a, b) a + b end x = calculation(5, 6, &method(:ankh)) # => 11 的对象:

x = calculation(5, 6, &:+)
# => 11