且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Hash.each和lambdas之间的不一致性

更新时间:2023-02-01 22:50:51

实际上,它似乎在1.8和1.9之间改变了,但是这个改变修复了1.9。 2,至少在我的测试:

  def strip_accents params 
thunk = lambda do | h |
key,value = h
case value
当String然后value.remove_accents!
当Hash then value.each(& thunk)
end
end
params.each(& thunk)
end
$ p>

这种方法也是向后兼容Ruby 1.8.7的。


I lifted the following example from 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

when I put it in the the rails console (irb), and call it with a hash, I get the following:

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>'

I understand that lambdas check arity, but I see two arguments in the lambda definition. If I change lambda do to Proc.new do, The code executes, and I get the expected result.

Josh's example is from 2008, so I'm assuming this is a difference in Ruby 1.8 and 1.9. What's going on here?

Indeed, it appears to have changed between 1.8 and 1.9, but this change fixes it for 1.9.2, at least in my tests:

def strip_accents params
  thunk = lambda do |h|
    key, value = h
    case value
    when String then value.remove_accents!
    when Hash   then value.each(&thunk)
    end
  end
  params.each(&thunk)
end

This approach turns out to be backward-compatible with Ruby 1.8.7, as well.