Monday, October 27, 2008

(8)lambda 和Proc

前面我们一再提到块的概念,你知道块只是一段代码,而不是一个对象。在Ruby中你可以通过Proc或者lambda来描述一个块,这时候这个块就是一个对象了,那么它也就有了方法call.
区分Proc和lambda可以在一个对象上调用lambda?方法,如果返回true就是lambda否则就是Proc
你可以通过a=Proc.new{|x| puts x}的方式定义一个Proc,你可以可以通过y=lambda{|x| x+1}的方式定义一个lambda。这两个的对象的却别在于Proc更像是一个块的定义,而lambda更像是一个方法的定义。比如下面的代码中,同样是return两种对象的行为是不一样的:
def test
  puts "entering method"
  p = Proc.new { puts "entering proc"; return } 
  p.call                 # 这里调用proc会使得方法return
  puts "exiting method"  # 这行永远不会执行
end
test

def test
  puts "entering method"
  p = lambda { puts "entering lambda"; return } 
  p.call                 # 调用lambda不会导致方法return
  puts "exiting method"  #现在这行会执行
end
test
另外这两种方式对参数的要求也是不一样的,比如:
p = Proc.new {|x,y| print x,y }
p.call(1)       # x,y=1:     如果缺少参数就用nil代替,打印 1 和 nil
p.call(1,2)     # x,y=1,2:   打印 12
p.call(1,2,3)   # x,y=1,2,3: 多余的参数被忽略了: 打印 12
p.call([1,2])   # x,y=[1,2]: 数组元素自动分配个每个参数: 打印 12



l = lambda {|x,y| print x,y }
l.call(1,2)     # 这样没有问题
l.call(1)       # 参数个数错误
l.call(1,2,3)   # 参数个数错误
l.call([1,2])   # 参数个数错误
l.call(*[1,2])  # 明确的告诉lambda这是一个数组参数,这可以正常运行。

No comments: