Usage de l'ampersand dans une méthode
Principe
En Ruby le préfixe & sur un paramètre de méthode signifie qu'on passe la référence comme Proc
def my_method(&block)  
  block.call("hello")  
end  
  
puts my_method { |value| value.upcase }   la sortie :
HELLOOn fait une closure sur la méthode
Autre façon de voir les choses
Cela correspond à faire :
def my_method(&block)  
  block.call("hello")  
end  
  
puts my_method(&Proc.new { |value| value.upcase })  
Compliquons un peu les choses
Je fais un monkey patch pour montrer que cela marche pour toutes méthodes de l'objet paramètre du call :
class String       
   def meth_wrapper_upcase  
        self.upcase  
   end  
end  
  
def my_method(&block)  
    block.call("hello")  
end  
  
puts my_method(&:meth_wrapper_upcase)  Ici le & s'applique au Symbol :meth_wrapper_upcase qui est transformé en Proc correspondant au code de la méthode de nom correspondant au Symbol
le&est identique à unSymbol#to_proc
Remarque : pour bien comprendre il faut aller regarder Symbol#to_procla documentation dit :

donc une closure sur :my_method  du bloc issue de la transformation de la méthode :meth_wrapper_upcase applicable sur le paramètre de closure.
En l’occurrence une String 
Du coup
Toutes ses lignes sont équivalentes :
[1, 2, 3].map(&:to_s)  
[1, 2, 3].map(&Proc.new { |number| number.to_s })  
[1, 2, 3].map { |number| number.to_s }  En ruby on préfèrera le sucre syntaxique &:sym_meth
Oui mais y a un petit problème
Si on prend le code suivant
def convert(*args)   
   args.map { |item| item.to_s(2) }   
end   ici on a un paramètre à la méthode to_s pour faire de la base 2
on va essayer de faire plus court
def convert(*args)  
   args.map(&:to_s(2))  
end  mais :to_s reste un Symbol, or syntaxiquement :symbole(params) n'est pas correct en Ruby donc :
/home/ruydiaz/labo/sandbox/test.rb:2: syntax error, unexpected '(', expecting ')'  args.map(&:to_s(2))   
                 ^  
/home/ruydiaz/labo/sandbox/test.rb:5: syntax error, unexpected end-of-input, expecting `end'  
et la c'est le drame ....
Mais pas tout à fait
on va jouer avec le caller et faire du forwarding
On commence avec un petit monkey patch on fera mieux par la suite
class Symbol  
  def with(*args, &block)  
  ->(caller, *rest) { caller.send(self, *rest, *args, &block) }  
  end  
end  
on va s'ajouter une réimplementation de Symbol pour ajouter le forwarder #with, ok le code pique un peu
En gros ça forward params et block vers le Symbol
Pour l'utiliser :
p [1,2,3,4,5].map(&:+.with(2))  
qui renvoie :
 [3, 4, 5, 6, 7]  
 On peut faire encore mieux
En ruby #call peut être abrévié #() , du coup le monkey patch devient :
class Symbol  
  def call(*args, &block)  
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }  
  end  
end  
  
p [1,2,3,4,5].map(&:+.(1))  On peut faire plus propre
Les monkey patch c'est pas bien, mieux vaut faire un Refinement
module AmpWithArgs  
  
  refine Symbol do  
   def call(*args, &block)  
  ->(caller, *rest) { caller.send(self, *rest, *args, &block) }  
   end  
  end  
  
end  du coup l'usage devient, dans le scope qui va bien :
using AmpWithArgs  
p [1,2,3,4,5].map(&:+.(1))   
      