Proc.new, proc, lambda 用于从block创建对象.
Ruby 1.8 中 , proc, lambda 都需要检查参数个数. Proc.new 不检查参数个数.
Ruby 1.9 中 , lambda 需要检查参数个数. Proc.new和proc 不检查参数个数.
block中调用的本地变量, 取自创建这个块时所在的本地变量, 而不是调用块时的本地变量.
下面都是Ruby 1.9 中的举例,
举例一 : x = "hello world"
ablock = lambda{ |y| puts(x) }
# 如果上面这行改成 ablock = lambda{ puts(x) }, 调用ablock都将报错, wrong number of arguments (1 for 0 (ArgumentError)
def aMethod(ablockArg)
x = "goodbye"
ablockArg.call(x)
end
puts(x) #=> "hello world"
ablock.call(x) #=> "hello world"
aMethod(ablock) #=> "hello world"
ablock.call(x) #=> "hello world"
puts(x) #=> "hello world"
输出都是 "hello world" 没有一个是goodbye, 原因是 " block中调用的本地变量, 取自创建这个块时所在的本地变量, 而不是调用块时的本地变量. "
举例二 :
x = "hello world"
ablock = proc{ puts(x) }
# proc 在1.9版本中不用检查参数个数, 所以不会报错
def aMethod(ablockArg)
x = "goodbye"
ablockArg.call(x)
end
puts(x) #=> "hello world"
ablock.call(x) #=> "hello world"
aMethod(ablock) #=> "hello world"
ablock.call(x) #=> "hello world"
puts(x) #=> "hello world"
举例三 :
x = "hello world"
ablock = Proc.new{ puts(x) }
Proc.new创建的块对象在调用是也不用检查传入的参数个数.
def aMethod(ablockArg)
x = "goodbye"
ablockArg.call(x)
end
puts(x) #=> "hello world"
ablock.call(x) #=> "hello world"
aMethod(ablock) #=> "hello world"
ablock.call(x) #=> "hello world"
puts(x) #=> "hello world"
举例四 :
严格来说, 上面的代码应该改成如下 :
x = "hello world"
ablock = lambda{ || puts(x) } # 表示不需要传入参数
# 或者 ablock = proc{ || puts(x) }
# 或者 ablock = Proc.new{ || puts(x) }
def aMethod(ablockArg)
x = "goodbye"
ablockArg.call()
end
puts(x) #=> "hello world"
ablock.call() #=> "hello world" # 调用时没有传入参数, 所以检查参数个数时是正确的.
aMethod(ablock) #=> "hello world"
ablock.call() #=> "hello world"
puts(x) #=> "hello world"