2010-09-08 16 views
9

Kann ich einen Ruby Hash aus einem Block erstellen?Create Hash mit Block (Ruby)

So etwas wie dies (auch wenn dies ausdrücklich nicht funktioniert):

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

Aus Neugier, versuchen Sie diesen Ansatz, weil Sie dies beim Erstellen neuer ActiveRecord-Objekte tun? –

Antwort

12

Ich kann nicht verstehen, warum

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

ist nicht für Sie arbeiten?

Ich wollte dies als Kommentar schreiben, aber ich konnte auf den Button, sorry

+0

Sie heben einen guten Punkt :) – user94154

+1

Sie brauchen 50 Ruf, bevor Sie Kommentare posten können. Sie sollten Kommentare hinterlassen können, nachdem Ihre Antwort aktualisiert wurde. – mikej

+0

danke, ich denke, ich sollte zuerst die Regeln lesen: D – gkaykck

17

In Ruby 1.9 (oder mit Active geladen, zum Beispiel in Rails) nicht finden, Sie Object#tap, zum Beispiel verwenden können:

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

Sie können einen Block zu Hash.new, übergeben, aber das dient die Standardwerte zu definieren:

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

Für das, was es wert ist, gehe ich davon aus, dass Sie ein größerer Zweck im Sinn mit diesem Block-Zeug. Die Syntax { :foo => 'bar', :baz => 'qux' } kann alles sein, was Sie wirklich brauchen.

+0

Ich habe eine Fixture-Datei, die mehr oder weniger eine Reihe von ActiveRecord create Methodenaufrufen ist. Wollte es für die Lesbarkeit hübsch machen. – user94154

3

Was mit

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

einen Block zu Hash.new Passing legt fest, was passiert, wenn Sie für einen nicht vorhandenen Schlüssel fragen.

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"} 

Wie der Suche nach einem nicht vorhandenen Schlüssel wird überschreiben alle vorhandenen Daten für :apple, :orange und :grape up, müssen Sie dies nicht geschehen soll.

Hier ist der Link zu der Hash.new specification.

0

Wie andere bereits erwähnt haben, kann eine einfache Hash-Syntax Sie bekommen, was Sie wollen.

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

Aber wenn Sie die „tap“ oder Hash mit einem Block-Methode verwenden, können Sie einige zusätzliche Flexibilität gewinnen, wenn Sie benötigen. Was ist, wenn wir aufgrund einer Bedingung keinen Artikel zum Apple-Standort hinzufügen möchten? Wir können jetzt etwas wie das Folgende tun: