2010-09-08 6 views
9

Puis-je créer un hachage Ruby à partir d'un bloc?Créer un hachage à l'aide d'un bloc (Ruby)

Quelque chose comme ça (bien que cela en particulier ne fonctionne pas):

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

Par curiosité, essayez-vous cette approche parce que vous faites cela lors de la création de nouveaux objets ActiveRecord? –

Répondre

12

Je ne comprends pas pourquoi

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

ne fonctionne pas pour vous?

Je voulais poster ce commentaire mais comme je ne pouvais pas trouver le bouton, désolé

+0

Vous soulevez un bon point :) – user94154

+1

vous avez besoin de 50 points de réputation avant de pouvoir poster des commentaires. Vous devriez pouvoir laisser des commentaires maintenant votre réponse a été upvoted. – mikej

+0

merci, je suppose que je devrais lire les règles d'abord: D – gkaykck

17

Dans Ruby 1.9 (ou avec ActiveSupport chargé, par exemple dans Rails), vous pouvez utiliser Object#tap, par exemple:

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

vous pouvez passer un bloc à Hash.new, mais qui sert à définir des valeurs par défaut:

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

pour ce que ça vaut, je suppose que vous avez un objectif plus large à l'esprit avec ce truc en bloc. La syntaxe { :foo => 'bar', :baz => 'qux' } peut être tout ce dont vous avez vraiment besoin.

+0

J'ai un fichier de fixture qui est plus ou moins un tas d'appels de méthode Create ActiveRecord. Voulait le faire pour la lisibilité. – user94154

3

Quel est le problème avec

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

Le passage d'un bloc à Hash.new spécifie ce qui se passe lorsque vous demandez une clé inexistante.

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

En regardant une volonté clé inexistante sur-écrire toutes les données existantes pour :apple, :orange et :grape, vous ne voulez pas que cela se produise. Voici le lien vers le Hash.new specification.

0

Comme d'autres l'ont mentionné, la syntaxe de hachage simple peut vous donner ce que vous voulez.

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

Mais si vous utilisez le « robinet » ou Hash avec une méthode de bloc, vous gagnez une certaine flexibilité supplémentaire si vous avez besoin. Que faire si nous ne voulons pas ajouter un article à l'emplacement de la pomme en raison de certaines conditions? Nous pouvons maintenant faire quelque chose comme ce qui suit:

# 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? 
}