2010-09-08 12 views
9

Posso creare un hash di Ruby da un blocco?Crea hash utilizzando il blocco (Ruby)

Qualcosa di simile (anche se questo particolare non funziona):

foo = Hash.new do |f| 
    f[:apple] = "red" 
    f[:orange] = "orange" 
    f[:grape] = "purple" 
end 
+0

Per curiosità, stai provando questo approccio perché lo fai quando crei nuovi oggetti ActiveRecord? –

risposta

12

non riesco a capire il motivo per cui

foo = { 
    :apple => "red", 
    :orange => "orange", 
    :grape => "purple" 
} 

non funziona per voi?

ho voluto pubblicare questo come commento, ma non riuscivo a trovare il pulsante, mi dispiace

+0

Hai sollevato un buon punto :) – user94154

+1

hai bisogno di 50 reputazione prima di poter postare commenti. Dovresti essere in grado di lasciare dei commenti ora che la tua risposta è stata upvoted. – mikej

+0

grazie, credo dovrei leggere prima le regole: D – gkaykck

17

In Ruby 1.9 (o con ActiveSupport caricato, ad esempio in Rails), è possibile utilizzare Object#tap, ad esempio:

foo = Hash.new.tap do |bar| 
    bar[:baz] = 'qux' 
end 

è possibile passare un blocco Hash.new, ma che serve per definire i valori di default:

foo = Hash.new { |hsh, key| hsh[key] = 'baz qux' } 
foo[:bar] #=> 'baz qux' 

per quel che vale, io parto dal presupposto che avete uno scopo più grande in mente con questo materiale di blocco. La sintassi { :foo => 'bar', :baz => 'qux' } potrebbe essere tutto ciò di cui hai veramente bisogno.

+0

Ho un file fixture che è più o meno un gruppo di ActiveRecord che crea chiamate di metodo. Volevo grazioso per la leggibilità. – user94154

3

Cosa c'è di sbagliato con

foo = { 
    apple: 'red', 
    orange: 'orange', 
    grape: 'purple' 
} 
4

Passando un blocco per Hash.new specifica che cosa accade quando si chiede una chiave inesistente.

foo = Hash.new do |f| 
    f[:apple] = "red" 
    f[:orange] = "orange" 
    f[:grape] = "purple" 
end 
foo.inspect # => {} 
foo[:nosuchvalue] # => "purple" 
foo # => {:apple=>"red", :orange=>"orange", :grape=>"purple"} 

Come cercare un tasto si inesistente sovrascrivere i dati esistenti per :apple, :orange e :grape, non si vuole che questo accada.

Questo è il collegamento allo Hash.new specification.

0

Come altri hanno già detto, la semplice sintassi dell'hash potrebbe farti ottenere ciò che desideri.

# Standard hash 
foo = { 
    :apple => "red", 
    :orange => "orange", 
    :grape => "purple" 
} 

Ma se si utilizza il "tap" o Hash con un metodo di blocco, si guadagna una certa flessibilità in più, se avete bisogno. Cosa succede se non vogliamo aggiungere un oggetto alla posizione di apple a causa di alcune condizioni? Ora possiamo fare qualcosa di simile al seguente:

# Tap or Block way... 
foo = {}.tap do |hsh| 
    hsh[:apple] = "red" if have_a_red_apple? 
    hsh[:orange] = "orange" if have_an_orange? 
    hsh[:grape] = "purple" if we_want_to_make_wine? 
}