可以使用&符号在Ruby中打印哈希吗?

时间:2012-10-02 00:25:05

标签: ruby arrays iterator

真的不知道如何标题这个问题。

考虑任意哈希(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)

4 个答案:

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

这是有效的,因为&symbolsymbol.to_proc的语法糖,这反过来又有一些魔力来返回一个块,该块将该消息发送给它作为参数接收的对象。

虽然这对您的示例不起作用(因为ENV中的对象不响应:bar),但您可以使用{{1}传递已存储在变量中的块}}:

&

答案 3 :(得分:1)

你可以使用两个块变量,而不是这样做:

each{|kv| puts kv.join(": ")}