2013-03-11 62 views
1

我已经创建了一个对象调用Proc.new并传递给它的块作为参数Proc`对象:混淆`Call`为`block`创建为`

a = Proc.new{|x| x = x*10; puts(x)} 
#=> #<Proc:[email protected](irb):3> 
a.call(10) 
#100 
#=> nil 
a.call(10,20) 
#100 
#=> nil 
a.call(10,20,40) 
#100 
#=> nil 

我没有使用任何splat operator(*)也。但是,如何阻止参数x能够忽略额外的参数?

当我们这样做时,我们会得到一个明确的错误,但为什么块参数不是这样?

def show(x) 
print "X::#{x}" 
end 
#=> nil 
show(10) 
#X::10#=> nil 
show(10,20) 
#ArgumentError: wrong number of arguments (2 for 1) 
#  from (irb):6:in `show' 
#  from (irb):10 
#  from C:/Ruby193/bin/irb:12:in `<main>' 

回答

2

Procs转换缺少参数为零,而lambda没有。

如果你想容忍错误,那么使用Procs。否则,你会想要去lambda

l = ->(x) { x = x * 10; puts x } 
=> #<Proc:[email protected](pry):12 (lambda)> 
l.call(10, 20) 
ArgumentError: wrong number of arguments (2 for 1) 
from (pry):12:in `block in <main>' 
+0

不要忘了lambda是一个Proc。 ''lambda {} .class => Proc'' – Intrepidd 2013-03-11 14:52:27

+0

确实,但它们的表现都不同:) – 2013-03-11 15:03:36

1

这就是Procs的工作原理,在内部,他们不关心是否传递了太多参数。

Proc#call将采用一组参数并将它们绑定到该块的参数,并且如果计数不匹配,则不会抱怨。

PROC lambda表达式,但会抱怨它,这就是它们的和定期特效之间的差别之一:

2.0.0p0 :006 > r = lambda { |x| puts x } 
=> #<Proc:[email protected](irb):6 (lambda)> 
2.0.0p0 :007 > r.call(1,2) 
ArgumentError: wrong number of arguments (2 for 1) 
from (irb):6:in `block in irb_binding' 
from (irb):7:in `call' 
from (irb):7 
from /Users/Intrepidd/.rvm/rubies/ruby-2.0.0-p0/bin/irb:16:in `<main>' 
+0

除此之外,你也可以splat proc块变量。 'lambda {| * x | x.join(',')} .call('foo','bar','baz')#=>“foo,bar,baz”' – 2013-03-11 14:40:04