为什么这个方法的参数是lambda,它是如何工作的

时间:2011-08-04 17:29:00

标签: ruby

取自编程ruby 1.9书:

def my_while(cond, &body)
 while cond.call
   body.call
 end
end

a=0

my_while -> { a < 3 } do
  puts a
  a += 1
end

产生

0

1

2

2 个答案:

答案 0 :(得分:4)

该方法需要一个显式参数cond,并假设这个“条件”是一个lambda / proc(假设是依靠cond.call成功的)并且必须传递给它方法my_while明确。 &语法通过将变量隐式转换为Proc对象(see 'The ampersand')来捕获变量中的方法块(如果存在)。

块不是Ruby中的真实对象,因此必须使用&符号语法进行转换。一旦块绑定到Proc,您就可以像在任何其他proc / lambda上一样发送call消息。

->语法是lambda的缩写,它将块转换为Proc对象(显式)。使用lambda和Proc.new之间也存在细微差别。再次,wikibook:

  

实际上,lambda和Proc.new之间存在两个细微差别。

     

首先,参数检查。 lambda状态的Ruby文档:等同于Proc.new,除了生成的Proc对象检查调用时传递的参数数量。

     

其次,从Proc处理退货的方式有所不同。从Proc.new返回来自封闭方法(就像从块中返回一样,稍后会更多):

def try_ret_procnew
  ret = Proc.new { return "Baaam" }
  ret.call
  "This is not reached"
end

# prints "Baaam"
puts try_ret_procnew
  

虽然从lambda返回更常规,但返回其调用者:

def try_ret_lambda
  ret = lambda { return "Baaam" }
  ret.call
  "This is printed"
end

# prints "This is printed"
puts try_ret_lambda
  

有了这个,我建议使用lambda而不是Proc.new,除非严格要求后者的行为。除了更酷,两个字符更短,它的行为不那么令人惊讶。

答案 1 :(得分:2)

作品-> { a < 3 }是lambda术语的快捷方式(随ruby 1.9引入)。这是传递给您的方法的第一个参数(即cond),而之后的块被分配给body。然后通过cond.call在您的方法中执行lambda。