我怎样才能使一个匿名对象分裂,以便我可以使用&方法呢?

时间:2011-09-15 02:41:34

标签: ruby ruby-1.9 splat arity

&method(:method_name)需要多个对象时,我想要使用method_name惯用法。我可以在Ruby 1.9下执行此操作吗?

例如,如果我有

def move_file(old_filename, new_filename)
  STDERR.puts "Moving #{old_filename.inspect} to #{new_filename.inspect}"
  # Implementation for careful moving goes here
end

old_filenames = ["foo.txt", "bar.txt", "hoge.ja.txt"]
new_filenames = ["foo_20110915.txt", "bar_20110915.txt", "hoge_20110915.ja.txt"]

代码

old_filenames.zip(new_filenames).each(&method(:move_file))

在Ruby 1.8下运行,但不在Ruby 1.9下运行。在Ruby 1.9下,它正在尝试move_file(["foo.txt", "foo_20110915.txt"])而不是move_file("foo.txt", "foo_20110915.txt")

我如何将它展开,以便它具有正确的灵性?

我知道的解决方法:

  1. def move_file(old_filename, new_filename)替换为def move_file(*arguments)
  2. each(&method(:move_file))替换为
    each{|old_filename, new_filename| move_file(old_filename, new_filename)}

2 个答案:

答案 0 :(得分:1)

相反

each{|old_filename, new_filename| move_file(old_filename, new_filename)}

你应该可以做到

each{|pair| move_file(*pair)}

但我不知道你是如何推出无块变体的(我也需要几次)。我想& -shorthand是为了使语法更简单,并不意味着被阻塞太多(例如它是作为数组传递数组,还是splatted)。 :)

答案 1 :(得分:0)

  
    

我如何将它展开,以便它具有正确的灵性?

  

我认为在兼容两个Ruby版本时,有一种方法可以做到这一点。你可以做的是将它包装成lambda

move_from_to = Proc.new {| * both | move_files(* both)}

事情是 - 块和proc arity是Ruby 1.9中解决的问题所以那里的行为可能存在差异。另请参阅prc.lambda?此处http://www.ruby-doc.org/core/classes/Proc.html,了解它对arity的作用。

这个问题也与你想要做的事情有关(解决方案是手动重新平面和取消平板):Inconsistency of arity between Hash.each and lambdas