Ruby unary operator &

Hi,

as you probably know, Ruby has a shorthand operator & which let’s us easily convert a Symbol to a Proc. Example:

%w(a b c).map(&:upcase) #=> ["A", "B", "C"]

Would be equivalent to:

%w(a b c).map { |c| c.upcase } => ["A", "B", "C"]

And the explanation is that &:upcase is calling to_proc on :upcase to create a Proc object.

However, I don’t seem to be able to use the operator anywhere outside the params of a method call:

:upcase.to_proc  => #<Proc:0x007febbc85ab38(&:upcase)>
&:upcase         => SyntaxError: syntax error, unexpected &

This would have been nice to use like this:

case number
when &:even?
  # ...
when &:prime?
  # ...
end

This works though:

case number
when :even?.to_proc
  # ...
when :prime?.to_proc
  # ...
end

In short, the unary operator & is only available on a method call, such as arr.map(&:upcase). Why??

1 Like

In case anyone was interested in the answer to this, I asked it on Stack Overflow: Ruby unary operator `&` only valid on method arguments - Stack Overflow

The explanation would be that the operator is creating a block, rather than a Proc object. Blocks, unlike Procs, aren’t objects so we can’t build them with an operator.

The block, however can then be converted to a Proc, for example:

def some_method(arg1, arg2, &given_block_as_proc)
  ...
end

But what the method does with its arguments/blocks is a different topic, I think.

However, this raises a new discussion: Why is the operator creating a block instead of a Proc?

I don’t have an answer for that but I would assume that initializing a Proc object is more expensive.