Proc 与 Lambda的区别
1、代码块、procs和lambda中的return语句
在一个代码块中的return语句不仅仅会从掉哦你该代码块的迭代器返回,它还会从调用迭代器的方法返回。
- def test
- puts "entering method"
- 1.times {puts "entering block"; return}
- puts "exiting method" #this line is never executed
- end
- test
- def test
- puts "entering method"
- p = Proc.new {puts "entering proc"; return}
- p.call
- puts "exiting method" #this line is never executed
- end
- test
- def test
- puts "entering method"
- p = -> {puts "entering lambda"; return}
- p.call
- puts "exiting method" #this line is executed
- end
- test
- def lambdaBuilder(msg)
- ->{puts msg; return}
- end
- def test
- puts "entering code"
- l = lambdaBuilder("hello world")
- l.call
- puts "exiting code" # this line is executed
- end
- test
2、break语句
proc中调用break语句,会是该代码块返回到它的迭代器,然后该迭代器再返回到它的调用方法。
- def iterator(&proc)
- puts "entering iterator"
- proc.call
- puts "exitring iterator" #this line is not executed
- end
- def test
- iterator {puts "entering proc"; break}
- end
- test
lambda中调用break语句,只是从lambda自身返回。
下面例子这种情况下,break和return语句一样。
- def test
- puts "entering test method"
- lambda = -> {puts "enterting lambda";break;puts "exitring lambda"}
- lambda.call
- puts "exitng test method"
- end
- test
- # =>entering test method
- # =>entering lambda
- # => exiting test method
3、顶级的next语句在代码块、proc和lambda中有相同的行为:它使调用代码块、proc和lambda的yield语句或call返回。
redo在proc和lambda中也有相同的行为,它让控制流转向proc和lambda的开始处。
4、传给proc和lambda的参数
调用proc使用的是yield语义,而调用lambda使用的是invocation语义。
proc实例:
- p = Proc.new {|x,y| print x,y}
- p.call(1) # 1 nil
- p.call(1,2) # 1,2
- p.call(1,2,3) # 1,2 extral rvalue discarded
- p.call([1,2]) #1,2 array automatically unpacked
- p.call([1,2,3,4]) # 1,2
lambda实例:
- puts "lambda******************************"
- l = ->(x,y){ print x,y }
- #l.call(1) #wrong number of arguments (1 for 2) (ArgumentError)
- l.call(1,2) # this works
- #l.call(1,2,3) #wrong number of arguments (3 for 2) (ArgumentError)
- #l.call([1,2]) #wrong number of arguments (1 for 2) (ArgumentError)