为什么这个ruby数组方法按照它的方式工作?

时间:2014-04-02 14:52:02

标签: ruby-on-rails ruby

当我有一个哈希或AR对象数组时,我喜欢这样做以访问某些字段:

products.map(&:upc_code)

有时我有一个哈希数组,而是用字符串键入,然后我不能使用&符号。所以我必须这样做:

people.map{ |p| p['Last Name'] }

我知道&符号可用于传递一个块,但我的问题是它为什么会像上面第一个语句中那样工作。它到底在做什么?

2 个答案:

答案 0 :(得分:2)

实际上如果在map等函数中没有找到块/ proc,则会调用to_proc函数作为参数。 在你的例子中实际上是转换:

products.map(&:upc_code) => products.map {|a| :upc_code.to_proc.call(a) } 

符号的实际to_proc方法看起来像(在ruby代码中):

class Symbol
  def to_proc
    proc { |o| o.send(self) }
  end
end

它返回一个proc,它调用作为参数传递的ruby对象的方法。你可以覆盖 像下面这样的符号的to_proc方法,以及支持哈希的字符串的to_proc。

class Symbol
  def to_proc
    proc { |o| 
     if o.is_a?(Hash)
      o.has_key?(self) ? o[self] : self.to_s.to_proc.call(o)
     else
       object.send(self)
     end
    }
  end
end

class String
  def to_proc
    proc { |o|  o.has_key?(self) ? o[self] : nil }
  end
end

a = [{"x" => 2}, {"x" => 3}]
puts a.map(&:x)
puts a.map(&"x")

结果将是:

=> [2, 3]
=> [2, 3]

答案 1 :(得分:1)

您的哈希不会简单地回复Last Name。即hash.key无效,hash[key]

如果您使用openstruct,突然之间就可以了!

require 'ostruct'
hash = { 'Last Name' => 1 }
[ OpenStruct.new(hash) ].map &:'Last Name'
=> [1]