如何将匿名对象 splattify 以便可以在其上使用 &method?
当 method_name
需要多个对象时,我想使用 &method(: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")
。
我如何将其splattify以使其具有正确的数量?
我知道的解决方法:
- 将
def move_file(old_filename, new_filename)
替换为def move_file(*arguments)
- 替换
each(&method(:move_file))
与每个{|旧文件名,新文件名| move_file(旧文件名,新文件名)}
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:
- Replace
def move_file(old_filename, new_filename)
withdef move_file(*arguments)
- Replace
each(&method(:move_file))
witheach{|old_filename, new_filename| move_file(old_filename, new_filename)}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
相反,
你应该能够做到
但我不知道你如何实现无块变体(我也需要它几次)。我猜 &- 简写是为了使语法更简单,并且并不意味着会被太多阻塞(例如,无论是将数组作为数组传递,还是将其展开)。 :)
Instead
you should be able to do
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). :)
我认为没有办法在兼容两个 Ruby 版本的同时做到这一点。你可以做的就是将它包装成一个 lambda
move_from_to = Proc.new {|*both| move_files(*both) }
问题是 - 块和过程是 Ruby 1.9 中解决的问题,因此那里的行为可能有所不同。另请参阅此处的
prc.lambda?
http:// www.ruby-doc.org/core/classes/Proc.html 了解它对数量的影响。这个问题也与你想要做的事情有关(解决方案是手动 resplat 和 unsplat ): Hash.each 和 lambda 之间的数量不一致
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