homeASCIIcasts

6: L'uso della Symbol to_proc per sostituire i blocchi 

(view original Railscast)

Other translations: En Es Fr

Other formats:

Written by Andrea Salicetti

La strana sintassi nella linea del find nel codice riportato qui sotto, con il simbolo preceduto dal carattere ampersand, è detta Symbol to_proc ed è un qualcosa che Rails aggiunge a Ruby.

class Project < ActiveRecord::Base
  has_many :tasks

  def self.all_names
    find(:all).collect(&:name)
  end
end

Useremo la facility Rails script/console per spiegare come funziona. Per prima cosa, prendiamo un array di Project.

asalicetti$ script/console
Loading development environment (Rails 2.3.5)
>> projects = Project.find(:all)
=> [#<Project id: 1, name: "Scrivi un altro ASCIIcast", created_at: "2010-04-12 12:32:40", updated_at: "2010-04-12 12:32:40">, #<Project id: 2, name: "Vai fuori a passeggio", created_at: "2010-04-12 12:35:20", updated_at: "2010-04-12 12:35:20">]

Ci sono due progetti e l’obiettivo è quello di ottenere un array contenente i nomi di tutti i progetti. Un modo per farlo sarebbe quello di usare il metodo collect, che accetta un blocco e restituisce il name di ogni Project. Il metodo collect iterata su di un array, esegue del codice (definito nel blocco) su ogni elemento dell’array, e restituisce un array contenente ogni risultato del codice del blocco eseguito su ogni singolo elemento dell’array originale.

>> projects.collect { |p| p.name }
=> ["Scrivi un altro ASCIIcast", "Vai fuori a passeggio"]

Symbol to_proc è una scorciatoia utilizzabile ogni volta in cui, come in questo caso, si vuole chiamare un metodo sull’oggetto che è mandato al blocco. Per fare ciò, si passa un parametro che inizia con un ampersand, seguito dal nome del metodo da invocare (nella sua forma simbolica):

>> projects.collect {&:name}
=> ["Scrivi un altro ASCIIcast", "Vai fuori a passeggio"]

Questa scorciatoia diventa particolarmente utile quando si vogliono combinare chiamate multiple:

>> projects.collect(&:name).collect(&:upcase)
=> ["SCRIVI UN ALTRO ASCIICAST", "VAI FUORI A PASSEGGIO"]

Ovviamente questa tecnica non è limitata al solo metodo collect; più in generale, può essere applicata a qualsiasi metodo che accetta un blocco. Per esempio i metodi any? e all? possono usare questa scorciatoia per vedere se tutti (all) o almeno uno (any) dei progetti sono validi, o persino per salvare tutti i nostri progetti.

>> projects.all?(&:valid?)
=> true
>> projects.any?(&:valid?)
=> true
>> projects.each(&:save!)
=> [#<Project id: 1, name: "Scrivi un altro ASCIIcast", created_at: "2010-04-12 12:32:40", updated_at: "2010-04-12 12:32:40">, #<Project id: 2, name: "Vai fuori a passeggio", created_at: "2010-04-12 12:35:20", updated_at: "2010-04-12 12:35:20">]

Nonostante la sua sintassi un tantino strana, Symbol to_proc è molto utile se usata quando si ha da concatenare metodi con blocchi.