Reputation: 118261
I have created an object calling Proc.new
and passing to it a block as an argument:
a = Proc.new{|x| x = x*10; puts(x)}
#=> #<Proc:0xd26fd8@(irb):3>
a.call(10)
#100
#=> nil
a.call(10,20)
#100
#=> nil
a.call(10,20,40)
#100
#=> nil
I didn't use any splat operator(*)
also. But how does then block parameter x
being able to ignore the extra arguments?
When we do the same we get a definite error, but why that's not the case with block parameter?
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>'
Upvotes: 1
Views: 70
Reputation: 19789
Procs
convert missing arguments to nil whereas lambda
does not.
If you want to be tolerant about errors then use Procs. Otherwise you'll want to go with lambda
l = ->(x) { x = x * 10; puts x }
=> #<Proc:0x007fada3be9468@(pry):12 (lambda)>
l.call(10, 20)
ArgumentError: wrong number of arguments (2 for 1)
from (pry):12:in `block in <main>'
Upvotes: 2
Reputation: 20868
That's how Procs work, internally, they don't care if too much arguments are passed.
Proc#call
will take an array of arguments and bind them to the arguments of the block, and won't complain if the count does not match.
Proc Lambdas, however, will complain about it, that's one of the differences between them and regular Procs :
2.0.0p0 :006 > r = lambda { |x| puts x }
=> #<Proc:0x007fac6913b600@(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>'
Upvotes: 1