2009-12-25 73 views
277

可能重复:
What does map(&:name) mean in Ruby?红宝石符号结肠快捷

在Ruby中,我知道,如果我这样做:

some_objects.each(&:foo) 

这是一样

some_objects.each { |obj| obj.foo } 

也就是说,&:foo创建块{ |obj| obj.foo },将它变成一个Proc,并将它传递给每个。为什么这个工作?它只是一个Ruby的特例,或者有理由说明它的工作原理是什么?

+0

这也被称为[椒盐卷饼](http://blog.honeybadger.io/how-ruby-ampersand-colon-works/)[冒号](http://technology.customink.com/blog/) 2015/06/08/ruby​​-pretzels /)语法。 – anothermh 2017-07-24 21:33:29

回答

430

这里发生的事情不是“和号和冒号”,而是“和号和对象”。这种情况下的冒号是符号。所以,有&:foo

&在对象上调用to_proc,并将其作为块传递给该方法。在Rails中,to_procSymbol实现的,所以这两个调用是等价的:

something {|i| i.foo } 
something(&:foo) 

此外,to_procSymbol用Ruby 1.8.7和1.9实现的,所以它实际上是一个“红宝石的事情”。

因此,总结:&在对象上调用to_proc,并将其作为块传递给方法,Ruby在Symbol上实现了to_proc

+71

更确切地说:&符解开“Proc”对象,以便它被传递,就好像它是一个文字块。只有当对象不是*已经是一个'Proc'对象时,它是否会调用'to_proc'。 – 2009-12-25 14:36:00

+0

符号#to_proc仅在Ruby中为原生> 1.9 – 2009-12-25 16:05:18

+6

@Steve:不,它也在1.8.7中。 p RUBY_VERSION #=>“1.8.7” p [“a”,“b”,“c”]。map(&:upcase) #=> [“A”,“B”,“C “] – 2009-12-25 16:24:18

69

&符号和符号的组合没有什么特别之处。这里有一个例子,(ab)使用正则表达式:

class Regexp 
    def to_proc 
    ->(str) { self =~ str ; $1 } 
    end 
end 
%w(station nation information).map &/(.*)ion/ 

=> ["stat", "nat", "informat"] 

或整数。

class Integer 
    def to_proc 
    ->(arr) { arr[self] } 
    end 
end 

arr = [[*3..7],[*14..27],[*?a..?z]] 
arr.map &4 
=> [7, 18, "e"] 

谁需要arr.map(&:fifth)当你有arr.map &4

+3

喜欢这个例子比答案标记正确 – Donato 2016-05-23 20:33:35