红宝石 – Proc.arity vs Lambda.arity

为什么proc和lambda为arity返回不同的值?

例如

proc   { |x = 0| }.arity       #=> 0
lambda { |a = 0| }.arity       #=> -1
proc   { |x=0,y| }.arity      #=> 1
lambda { |x=0,y| }.arity      #=> -2

见:http://www.ruby-doc.org/core-2.0/Proc.html#method-i-arity

解决方法

根据您链接的文档:

Returns the number of arguments that would not be ignored. If the block is declared to take no arguments,returns 0. If the block is kNown to take exactly n arguments,returns n. If the block has optional arguments,return -n-1,where n is the number of mandatory arguments. A proc with no argument declarations is the same a block declaring || as its arguments.

该文档忘记提到的是procs和lambda不以正确的方式处理参数,例如:

>> p = proc { |a = 1,b| b }
=> #<Proc:0x007ff0091ef810@(irb):1>
>> l = lambda { |a = 1,b| b }
=> #<Proc:0x007ff0098099f8@(irb):2 (lambda)>
>> p.call
=> nil
>> l.call
ArgumentError: wrong number of arguments (0 for 1..2)
    from (irb):2:in `block in irb_binding'
    from (irb):4:in `call'
    from (irb):4
    from /usr/local/bin/irb:12:in `<main>'

编辑:来自O’Reilly的Ruby编程语言是具有更多细节的Ruby编程语言:

6.5.3 The Arity of a Proc

The arity of a proc or lambda is the number of arguments it expects.
(The word is derived from the “ary” suffix of unary,binary,ternary,
etc.) Proc objects have an arity method that returns the number of
arguments they expect. For example:

06001

The notion of arity gets confusing when a Proc accepts an arbitrary
number of argu- ments in an *-prefixed final argument. When a Proc
allows optional arguments,the arity method returns a negative number
of the form -n-1. A return value of this form indicates that the Proc
requires n arguments,but it may optionally take additional arguments
as well. -n-1 is kNown as the one’s-complement of n,and you can
invert it with the ~ operator. So if arity returns a negative number
m,then ~m (or -m-1) gives you the number of required arguments:

06002

There is one final wrinkle to the arity method. In Ruby 1.8,a Proc
declared without any argument clause at all (that is,without any ||
characters) may be invoked with any number of arguments (and these
arguments are ignored). The arity method returns –1 to indicate that
there are no required arguments. This has changed in Ruby 1.9: a Proc
declared like this has an arity of 0. If it is a lambda,then it is an
error to invoke it with any arguments:

06003

编辑2:Stefan在评论增加了他们不同的确切原因:

http://www.ruby-doc.org/core-2.0/Proc.html#method-i-call

For procs created using lambda or ->() an error is generated if the wrong number of parameters are passed to a Proc with multiple parameters. For procs created using Proc.new or Kernel.proc,extra parameters are silently discarded.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...