真的不知道如何标题这个问题。
考虑任意哈希(ENV很方便):
ENV.each { |key, val| puts key + ': ' + val }
LC_MESSAGES: en_US.utf-8
LC_COLLATE: en_US.utf-8
PWD: /Users/baller/ive_fallen_and_i_cant_get_up
LC_MONETARY: en_US.utf-8
是否可以使用&amp ;:简写来执行此操作?
foo.each(&:bar)
答案 0 :(得分:1)
默认情况下,没有。
要做你想做的事,你需要在Array类中添加一个方法,它打印出你想要的方式,如:
class Array
def bar
puts "#{self[0]}: #{self[1]}"
end
end
,ENV.each(&:bar)
将完成您的期望。
那就是说,我不推荐这个。只有当实用程序远远超过未来冲突的可能性时,才能添加到基类,并且此方法对于包含至少2个元素的数组非常专业。
不相关,但通过+
连接字符串比使用插值慢得多。它不必要地创建额外的对象。
答案 1 :(得分:1)
在您的示例中,使用&:bar
代替块将导致在给定对象上调用#to_proc
,在本例中为符号:bar
。 Ruby中Symbol的#to_proc
实现基本上将foo.each(&:bar)
扩展为foo.each { |i| i.bar }
。由于哈希产生了两个参数,因此本例中的i
是键的数组,值为args。这就是为什么你必须扩展Array
(如@ x1a4所述)来让你的哈希按照预期处理&:bar。
作为替代方案,您可以创建自己的类来响应#to_proc
,或者只是将块实现为Proc:
class Bar
def to_proc
Proc.new { |key, val| puts key + ': ' + val }
end
end
bar = Bar.new
# or
bar = Proc.new { |key, val| puts key + ': ' + val }
使用手柄到条形图,您可以将& bar代替块传递给像ENV这样的哈希。所以给定一个哈希,foo:
foo.each(&bar)
关于此主题的更多阅读的好文章:http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html
答案 2 :(得分:1)
通常,如果集合的元素响应该方法,则可以这样做。例如:
class Foo
attr_reader :bar
def initialize(bar)
@bar = bar
end
end
foos = [Foo.new("one"), Foo.new("two"), Foo.new("three")]
p foos.map(&:bar) #=> ["one", "two", "three"]
这是有效的,因为&symbol
是symbol.to_proc
的语法糖,这反过来又有一些魔力来返回一个块,该块将该消息发送给它作为参数接收的对象。
虽然这对您的示例不起作用(因为ENV
中的对象不响应:bar
),但您可以使用{{1}传递已存储在变量中的块}}:
&
答案 3 :(得分:1)
你可以使用两个块变量,而不是这样做:
each{|kv| puts kv.join(": ")}