为什么proc和lambda返回的参数值不同?
例如:
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
发布于 2013-06-07 22:43:35
根据您链接到的文档:
返回不会被忽略的参数数量。如果声明块不接受任何参数,则返回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>'编辑:O‘’Reilly的Ruby编程语言具有更多的细节:
6.5.3进程的多重性
proc或lambda的数量就是它所期望的参数数量。(该词源于“ary”后缀,如一元、二进制、三元等。)Proc对象有一个arity方法,它返回它们期望的参数数量。例如:
lambda{||} => #lambda 0.不应使用任何参数lambda{|x| x}.arity # => 1。应使用一个参数lambda{|x,y| x+y}.arity # => 2。应使用两个参数
当Proc接受以*为前缀的最终参数中的任意数量的参数时,实数的概念变得令人困惑。当Proc允许可选参数时,a方法返回形式为-n-1的负数。这种形式的返回值表明Proc需要n个参数,但它也可以选择性地接受其他参数。- n -1称为n的1的补码,您可以使用~运算符对其进行反转。因此,如果arity返回负数m,那么~m (或-m-1)将提供所需参数的数量:
lambda {|*args|}.arity # => -1。~-1 = -(-1)-1 =0参数需要lambda {|first,*rest|}.arity # => -2。~-2 = -(-2)-1 =需要1个参数
对于arity方法,有一个最后的问题。在Ruby 1.8中,完全不带参数子句(即没有任何||字符)声明的Proc可以使用任意数量的参数(这些参数被忽略)来调用。are方法返回-1,表示没有必需的参数。这种情况在Ruby 1.9中发生了变化:像这样声明的Proc的参数为0。如果它是一个lambda,那么使用任何参数调用它都是错误的:
将lambda {}.arity #-1放在Ruby1.8中;0放在Ruby1.9中
编辑2: Stefan在评论中添加了他们不同的确切原因:
http://www.ruby-doc.org/core-2.0/Proc.html#method-i-call
对于使用
lambda或->()创建的procs,如果将错误数量的参数传递给具有多个参数的Proc,则会生成错误。对于使用Proc.new或Kernel.proc创建的procs,额外的参数将以静默方式丢弃。
发布于 2013-06-07 22:44:44
正如这里提到的:(Differences between Proc and Lambda),procs和lambda之间的主要区别之一是“就像方法一样,lambda有严格的参数检查,而非lambda Proc有松散的参数检查,就像块一样。”
因此,由于数量是基于所需参数的数量,这将在procs和lambdas之间变化。
发布于 2013-06-08 04:30:11
读完其他两个答案后,我猜#中的方法是如履薄冰。对于固定数量的有序参数,#arity过去是完全OK的方法。然后,当添加可选参数时,为了坚持用单个整数表示数量,负号被用作标志。但是,参数字段信息已经被丢弃了,例如。1ary或2ary -> a, b=1 { a + b }表示与-> a, *b { a + b.sum }相同的大小(-2),参数为1到任意数量。在1.9中的#arity行为更改之后,2.0中又出现了另一个打击,其中引入了命名参数,而#arity完全没有注意到这一点。同样,将有强制的和可选的命名参数,加上使用hash splash **收集任意数量的命名参数的可能性。我希望#arity方法在未来再次改变它的行为……
https://stackoverflow.com/questions/16986471
复制相似问题