The shorthand syntax for mapping over a collection and calling a single method on each item is:

But what does the & do?

It calls to_proc on the given variable, in this case a Symbol, :name.

:name.to_proc # => Proc

A proc is an object which wraps an block (function) making it callable. # => 'Kris'

The proc returned by to_proc is passed to #map.

I think Symbol#to_proc, being part of the core library, is implemented in the interpreter itself as C code (or Java in the case of JRuby), but if it where implemented in Ruby code it might look something like:

class Symbol
  def to_proc { |item| item.public_send(self) }

The above to_proc method returns a proc which accepts a single argument and calls #public_send on it passing in itself the symbol, :name, as the argument.

When used with map it is the equivalent to: { |item| item.public_send(:name) }

Which is essentially the same as the longer way of writing the original code: { |it| }

Any object that has a to_proc method can be referenced after & in method arguments.

String does not define to_proc which is why"name") fails.

You actually get a TypeError not an NoMethodError.

Method defines to_proc which is why you can use methods too after an & as the argument to #map and similar methods.

def add_one(num)
  num + 1

method(:add_one) # => Method
method(:add_one).to_proc # => Proc
method(:add_one) # => 2

[1,2,3].map(&method(:add_one)) # => [2,3,4]

Method#to_proc as Ruby would potentially be something like:

class Method
  def to_proc { |item| }

This is why you can also put a proc after & because Proc#to_proc simply returns itself.

to_s = { |item| item.to_s }

[1,2,3].map(&to_s) # => ['1', '2', '3']

In ruby it would simply be:

class Proc
  def to_proc

I think this goes to show just how well Ruby exploits both object and functional concepts.

Some final notes:

proc is a method on Kernel, thus avalible everwhere, and is shorthand for

proc {}.class # => Proc

A lambda is a type of Proc:

lambda {}.class # => Proc
-> {}.class # => Proc

Procs can be called in different ways:

adder = proc { |i| i + 1 } # => 2
adder.(1) # => 2
adder[1] # => 2
adder === 1 # => 2

The final === is kinda strange, this is so procs can be used in case statements. It is only useful, in a case, if the proc returns true or false.

hot  = proc { |n| n > 20 }
cold = proc { |n| n < 0 }

case temperature
when hot
  # ...
when cold
  # ...
  # ...

Now we are off topic, so time to finish up.