开发者

How can I splattify an anonymous object so I can use &method on it?

I'm wanting to use the &method(:method_name) idiom when there's more than one object required by method_name. Can I do this under Ruby 1.9?

For example, if I've got

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"]

the code

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

works under Ruby 1.8, but not under Ruby 1.9. Under Ruby 1.9, it's trying to do move_file(["foo.txt", "foo_20110915.txt"]) instead of move_file("foo.txt", "foo_20110915.txt").

How do I splattify it so it has the correct arity?

Workarounds I'm 开发者_如何转开发aware of:

  1. Replace def move_file(old_filename, new_filename) with def move_file(*arguments)
  2. Replace each(&method(:move_file)) with

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


Instead

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

you should be able to do

each{|pair| move_file(*pair)}

But I don't know how you'd pull off blockless variant (I needed it couple of times as well). I guess &-shorthand was made to make the syntax simpler, and is not meant to be clogged much (whether it will be passed an array as an array, or splatted, for example). :)


How do I splattify it so it has the correct arity?

I don't think there is a way to do this while being compatible to both Ruby versions. What you could do is wrap it into a lambda

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

The thing is - block and proc arity is something that got addressed in Ruby 1.9 so there might be a difference in behavior there. Also see prc.lambda? here http://www.ruby-doc.org/core/classes/Proc.html for info on what it does to the arity.

This question is also related to what you want to do (the solution there is to resplat and unsplat manually): Inconsistency of arity between Hash.each and lambdas

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜