Ruby 为什么这个方法的参数是lambda,它是如何工作的
摘自ruby 1.9编程手册:Ruby 为什么这个方法的参数是lambda,它是如何工作的,ruby,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 def my_while(cond和body) 当康德打电话时 body.call 终止 终止 a=0 我的while->{a{a{a语法是lambda的缩写,它(显式地)将块转换为Proc对象。使用lambd
def my_while(cond, &body)
while cond.call
body.call
end
end
a=0
my_while -> { a < 3 } do
puts a
a += 1
end
def my_while(cond和body)
当康德打电话时
body.call
终止
终止
a=0
我的while->{a<3}do
提出
a+=1
终止
产生:
0
一,
2这个片段
->{a<3}
是lambda术语的快捷方式(由ruby 1.9引入)。这是传递给方法的第一个参数(即cond
),而随后的块被分配给body
。lambda然后通过cond.call在方法内部执行片段->{a<3}
是lambda术语的快捷方式(由ruby 1.9引入)。这是传递给方法的第一个参数(即cond
),而随后的块被分配给body
。然后通过cond.call在方法内部执行lambda
该方法需要一个显式参数cond
,并且该“条件”被假定为lambda/proc(该假设是通过依赖cond.call
来实现的),并且必须在显式时传递给方法my\u。&
语法通过隐式地将方法块转换为Proc
对象()来捕获变量中的方法块(如果存在)
块在Ruby中不是真实的对象,因此必须使用符号和语法进行转换。一旦该块绑定到一个Proc,就可以像在任何其他Proc/lambda上一样在其上发送调用
消息
->
语法是lambda
的缩写,它(显式地)将块转换为Proc对象。使用lambda和Proc.new之间也有细微的区别。同样,维基百科:
实际上,lambda和Proc.new之间有两个细微的区别
首先,参数检查。lambda的Ruby文档声明:相当于Proc.new,除了生成的Proc对象检查调用时传递的参数数量之外
其次,从Proc处理返回的方式有所不同。来自Proc.new的返回来自封闭方法(就像来自块的返回一样,稍后将对此进行详细介绍):
而从lambda返回的行为更为常规,返回到调用方:
有鉴于此,我建议使用lambda而不是Proc.new,除非严格要求后者的行为。除了让两个角色大大缩短之外,它的行为也不那么令人惊讶
该方法需要一个显式参数cond
,并且该“条件”被假定为lambda/proc(该假设是通过依赖cond.call
来实现的),并且必须在显式时传递给方法my\u。&
语法通过隐式地将方法块转换为Proc
对象()来捕获变量中的方法块(如果存在)
块在Ruby中不是真实的对象,因此必须使用符号和语法进行转换。一旦该块绑定到一个Proc,就可以像在任何其他Proc/lambda上一样在其上发送调用
消息
->
语法是lambda
的缩写,它(显式地)将块转换为Proc对象。使用lambda和Proc.new之间也有细微的区别。同样,维基百科:
实际上,lambda和Proc.new之间有两个细微的区别
首先,参数检查。lambda的Ruby文档声明:相当于Proc.new,除了生成的Proc对象检查调用时传递的参数数量之外
其次,从Proc处理返回的方式有所不同。来自Proc.new的返回来自封闭方法(就像来自块的返回一样,稍后将对此进行详细介绍):
而从lambda返回的行为更为常规,返回到调用方:
有鉴于此,我建议使用lambda而不是Proc.new,除非严格要求后者的行为。除了让两个角色大大缩短之外,它的行为也不那么令人惊讶
因此,lambda仅用于在methodYes内通过cond.call调用它-第一个参数cond
是显式的,预期是“可调用的”,而&block
是隐式参数,捕获方法的块。因此使用lambda只是为了能够通过方法内部的cond.call调用它。是-第一个参数cond
是显式的,预期是“可调用的”,而&block
是一个隐式参数,用于捕获方法的块。
def try_ret_procnew
ret = Proc.new { return "Baaam" }
ret.call
"This is not reached"
end
# prints "Baaam"
puts try_ret_procnew
def try_ret_lambda
ret = lambda { return "Baaam" }
ret.call
"This is printed"
end
# prints "This is printed"
puts try_ret_lambda