当前位置: 代码迷 >> 综合 >> Ruby 中的 block、proc、lambda
  详细解决方案

Ruby 中的 block、proc、lambda

热度:38   发布时间:2023-12-09 09:37:48.0



原文来自于:
http://railstalk.com/?p=28

Ruby Block先举两个例子,each使用block
[1,2,3,4,5].each do | number |puts number
end[1,2,3,4,5].each { |number |puts number
}可以看出我们使用do...end 或者 {...} 来调用block。
{ | number | puts number }这个就是Ruby的blockRuby中的block其实就相当于Javascript中的异步函数,存储了调用函数,直到被调用。其中 | number | 只是异步函数的参数。Ruby 的 block 传递给函数时,使用 █ 这样的形式,在参数前加 & ,则参数被识别为 block。 调用 block 时,需要时 call 。
block.call(...)同时,Ruby block 可以在函数中不声明参数,而只使用yield。如:
def call_block_without_argumentyield        
endcall_block_without_argument { puts "Hello Block" }Ruby ProcProc 对象是一段捆绑在一起的代码,被设置为局部变量,可以在上下文中被调用。例:
multiply = Proc.new { | a, b | puts a * b }
multiply.call( 3, 4 )  # print out 12同时,可以绑定一系列变量到 Proc ,这样在调用中可以使用这些变量。例:
def multiply_with( factor )return Proc.new { | number | number * factor }
endmultiply_with 函数将返回一个 Proc 对象,同时包含一个参数。
multiply_with_10 = multiply_with( 10 )
# call multiply_with_10 with a number
multiply_with_10.call( 12 ) # return 120
# or you can call in another way
multiply_with_10[12] # return 120可以看到 factor 参数在函数中在创建是赋给 Proc,然后就会永久的存在 Proc 中,这样就可以随时调用了。另外,Proc 可以象 Block 一样传递给函数。当然有些不一样的地方。
def print_with_postfix( postfix )return Proc.new { |printing_content| puts "#{printing_content} #{postfix}" }end
然后可以把返回的 Proc 对象象其他函数参数值一样传递给 print_with_postfix 函数。print_with_postfix_bye = print_with_postfix( "bye" )
print_with_postfix_end = print_with_postfix( "end" )def print_content( content, print_style )print_style.call( content )
endprint_content( "Hello world", print_with_postfix_bye ) # print out Hello world bye
print_content( "Hello world", print_with_postfix_end ) # print out Hello world endBlock 和 Proc 间的转换使用 & 。
在函数调用时我们使用 &variable 类似的格式来传递参数值,这就把 Block 转换成了 Proc, 这样就可以在函数中使用 call 来调用。同时也可以使用 & 将 Proc 对象转换成 Block。multiply_with_10 = Proc.new { | number | puts number * 10 }
[1,2,3,4].each( μltiply_with_10 )  
# 10
# 20
# 30
# 40因为在 each 函数中接收 block 作为参数值。而这里我们使用了一个 Proc,就需要加上 & 来把 Proc 转换为 Block。Lambda
lambda 是创建 Proc 的函数
multiply_lambda_proc = lambda { | x, y | x * y }
# and we can call as a normal Proc
multiply_lambda_proc.call( 3, 4 ) # return 12但 lambda 和 proc 有两个不同点:
lambda 对参数做检查,而 proc 不检查。例:multiply_lambda_proc = lambda { | x, y | x * y }
multiply_proc = Proc.new { | x, y | x * y }multiply_lambda_proc.call( 3, 4, 5 ) # ArgumentError: wrong number of arguments (3 for 2)
multiply_proc( 3, 4, 5 ) # return 12 as normal# This last command's error shows that Proc auto assigns missing argument with nil
multiply_proc( 3 )  # TypeError: nil can't be coerced into Fixnumlambda 返回到调用者的函数,而 proc 返回到内部的函数。def return_from_procruby_proc = Proc.new { return "return from a Proc" }ruby_proc.callreturn "The function will NOT reach here because a Proc containing a return statement has been called"
enddef return_from_lambdaruby_lambda = lambda { return "return from lambda" }ruby_lambda.callreturn "The function will reach here"
endputs return_from_proc # display return from proc
puts return_from_lambda # display The function will reach here在这个例子中,可以看到 proc 包含的一个 return 语句被调用,将会返回整个函数,而lambda 
  相关解决方案