Proc.arity与Lambda.arity

Sno*_*ash 14 ruby

为什么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
Run Code Online (Sandbox Code Playgroud)

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

Den*_*rdy 13

根据您链接到的文档:

返回不会被忽略的参数数.如果声明该块不带参数,则返回0.如果已知该块正好取n个参数,则返回n.如果块具有可选参数,则返回-n-1,其中n是必需参数的数量.没有参数声明的proc与声明||的块相同 作为其论点.

文档忘记提到的是,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>'
Run Code Online (Sandbox Code Playgroud)

编辑:来自O'Reilly的Ruby编程语言是一个有更多细节的编程语言:

6.5.3 Proc的Arity

proc或lambda的arity是它期望的参数数量.(这个词来自一元,二元,三元等的"ary"后缀.)Proc对象有一个arity方法,它返回它们期望的参数个数.例如:

lambda{||}.arity # => 0. No arguments expected
lambda{|x| x}.arity # => 1. One argument expected
lambda{|x,y| x+y}.arity # => 2. Two arguments expected
Run Code Online (Sandbox Code Playgroud)

当Proc在*-prefixed final参数中接受任意数量的论证时,arity的概念会变得混乱.当Proc允许可选参数时,arity方法返回形式为-n-1的负数.此表单的返回值表示Proc需要n个参数,但也可以选择使用其他参数.-n-1被称为n的一个补码,你可以用〜运算符将它反转.因此,如果arity返回负数m,那么~m(或-m-1)将为您提供所需参数的数量:

lambda {|*args|}.arity # => -1. ~-1 = -(-1)-1 = 0 arguments required
lambda {|first, *rest|}.arity # => -2. ~-2 = -(-2)-1 = 1 argument required
Run Code Online (Sandbox Code Playgroud)

arity方法有一个最后的皱纹.在Ruby 1.8中,可以使用任意数量的参数调用一个没有任何参数子句的Proc(也就是说,没有任何||字符)(并忽略这些参数).arity方法返回-1表示没有必需的参数.这在Ruby 1.9中发生了变化:声明像这样的Proc具有0的arity.如果它是lambda,那么用任何参数调用它是错误的:

puts lambda {}.arity # –1 in Ruby 1.8; 0 in Ruby 1.9
Run Code Online (Sandbox Code Playgroud)

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

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

对于procs创建使用lambda,->()如果将错误数量的参数传递给Proc具有多个参数的参数,则会生成错误.对于procs使用Proc.new或创建Kernel.proc,将以静默方式丢弃额外参数.

  • 来自[`Proc#call`](http://www.ruby-doc.org/core-2.0/Proc.html#method-i-call):*"对于使用`lambda`或` - >创建的proc( )如果将错误数量的参数传递给具有多个参数的Proc,则会生成错误.对于使用`Proc.new`或`Kernel.proc`创建的proc,将以静默方式丢弃额外的参数."* (3认同)