取自编程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
答案 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。