Как я могу splattify анонимный объект, чтобы я мог использовать & метод на нем?

Я хочу использовать &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 ответа

Вместо

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

ты должен быть в состоянии сделать

each{|pair| move_file(*pair)}

Но я не знаю, как бы вы выполнили безблочный вариант (он мне тоже понадобился пару раз). Я полагаю, что &-shorthand был сделан, чтобы упростить синтаксис, и он не должен сильно забиваться (например, будет ли он передан в виде массива или разделен на части).:)

Как мне его разделить, чтобы он имел правильную арность?

Я не думаю, что есть способ сделать это, будучи совместимым с обеими версиями Ruby. Что вы могли бы сделать, это обернуть его в лямбду

move_from_to = Proc.new {|* оба | move_files(* оба) }

Дело в том, что в Ruby 1.9 решаются проблемы с блоком и производительностью, поэтому в них может быть различие в поведении. Также см prc.lambda? здесь http://www.ruby-doc.org/core/classes/Proc.html для получения информации о том, что это делает с Arity.

Этот вопрос также связан с тем, что вы хотите сделать (есть решение перераспределить и убрать вручную): несоответствие арности между Hash.each и lambdas

Другие вопросы по тегам