Hash.each和lambdas之间的arity不一致
我从Josh Susser那里得到了以下例子
def strip_accents params
thunk = lambda do |key,value|
case value
when String then value.remove_accents!
when Hash then value.each(&thunk)
end
end
params.each(&thunk)
end
当我把它放在rails控制台(irb)中,并用哈希调用它时,我得到以下内容:
ruby-1.9.2-p136 :044 > `ruby --version`
=> "ruby 1.9.2p136 (2010-12-25 revision 30365) [i686-linux]n"
ruby-1.9.2-p136 :045 > strip_accents({:packs=>{:qty=>1}})
ArgumentError: wrong number of arguments (1 for 2)
from (irb):32:in `block in strip_accents'
from (irb):37:in `each'
from (irb):37:in `strip_accents'
from (irb):45
from /longpathtrimedforclarity/console.rb:44:in `start'
from /longpathtrimedforclarity/console.rb:8:in `start'
from /longpathtrimedforclarity/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
我理解lambdas检查arity,但我在lambda定义中看到两个参数。如果我将lambda do
改为Proc.new do
,代码执行,我得到预期的结果。
Josh的例子是从2008年开始的,所以我假设这是Ruby 1.8和1.9的不同之处。这里发生了什么?
没有找到相关结果
已邀请:
2 个回复
古擅坛犯
这种方法也可以向后兼容Ruby 1.8.7。
喷乡顾沥沪
,就像其他每个
方法一样,为块产生一个参数。在
的情况下,该一个参数是由键和值组成的双元素数组。 所以,
产生一个参数,但是你的lambda有两个必需参数,因此你会得到一个arity错误。 它适用于块,因为块对它们的参数不太严格,特别是,如果一个块有多个参数,但只获得一个参数,它将尝试解析参数,就像它已经用splat传入一样。 有两种
s:lambdas和non-lambdas(令人困惑的是,后者通常也被称为
s)。 Lambdas在
关键字的行为和(更重要的是,对于这种情况)如何绑定参数方面的行为类似于方法,而非lambda
在how11ѭ和参数绑定工作方面的行为类似于块。这就是为什么
(它创造了一个非lambda
)的作用,但是
(显然创造了一个lambda)却没有。 您可以通过拨打
来检查
是否是lambda。 如果要解构参数,则必须明确地这样做,就像定义方法时一样:
并且,是的,对于块,
s和lambdas的参数绑定更为理智的方法是Ruby 1.9中主要的向后不兼容的变化之一。