Ruby ampersand colon shortcut [duplicate]

2018-12-31 04:01发布

Possible Duplicate:
What does map(&:name) mean in Ruby?

In Ruby, I know that if I do:

some_objects.each(&:foo)

It's the same as

some_objects.each { |obj| obj.foo }

That is, &:foo creates the block { |obj| obj.foo }, turns it into a Proc, and passes it to each. Why does this work? Is it just a Ruby special case, or is there reason why this works as it does?

标签: ruby
2条回答
梦醉为红颜
2楼-- · 2018-12-31 04:14

Your question is wrong, so to speak. What's happening here isn't "ampersand and colon", it's "ampersand and object". The colon in this case is for the symbol. So, there's & and there's :foo.

The & calls to_proc on the object, and passes it as a block to the method. In Rails, to_proc is implemented on Symbol, so that these two calls are equivalent:

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

Also, to_proc on Symbol is implemented in Ruby 1.8.7 and 1.9, so it is in fact a "ruby thing".

So, to sum up: & calls to_proc on the object and passes it as a block to the method, and Ruby implements to_proc on Symbol.

查看更多
宁负流年不负卿
3楼-- · 2018-12-31 04:28

There's nothing special about the combination of the ampersand and the symbol. Here's an example that (ab)uses the regex:

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

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

Or integers.

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

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

Who needs arr.map(&:fifth) when you have arr.map &4?

查看更多
登录 后发表回答