2009-05-08 5 views
9

Y a-t-il une meilleure façon de faire cela? (Il semble maladroit)Une meilleure façon de remplir un hachis Ruby?

form_params = {} 
form_params['tid'] = tid 
form_params['qid'] = qid 
form_params['pri'] = pri 
form_params['sec'] = sec 
form_params['to_u'] = to_u 
form_params['to_d'] = to_d 
form_params['from'] = from 
form_params['wl'] = wl 
+0

La saveur précise de clunkiness est appelée SEC, https://en.wikipedia.org/wiki/Don't_repeat_yourself. –

Répondre

8

Légère modification à ce qui précède, puisque votre exemple avait les clés de chaîne:

form_params = {} 
%w(tid qid pri sec to_u to_d from wl).each{|v| form_params[v] = send(v)} 
20
form_params = { "tid" => tid, "qid" => qid }  

Ou vous pouvez faire

form_params = Hash["tid", tid, "qid", qid]  #=> {"tid"=>tid, "qid"=>qid} 
form_params = Hash["tid" => tid, "qid" => qid] #=> {"tid"=>tid, "qid"=>qid} 
form_params = Hash[tid => tid, qid => qid]  #=> {"tid"=>tid, "qid"=>qid} 

(nb. Le dernier est nouveau pour 1.9 et il est la clé symbols au lieu de strings)

{tid: tid, qid: qid}

Les clés et les valeurs apparaissent par paires, il doit donc y avoir une nu mber d'arguments.

+2

À partir de Ruby 1.9, si vous êtes OK avec les clés étant des symboles plutôt que des chaînes, vous pouvez aussi dire {tid: tid, qid: qid}. – Chuck

+0

: ne fonctionne pas, => ne – Schildmeijer

+0

Non, le côlon fonctionne comme je l'ai dit. Je viens de tester. ruby -e "tid = 12; puts ({tid: tid})" imprime "{: tid => 12}". La forme => ne fonctionne pas - elle imprime {12 => 12}. – Chuck

7

Si la performance est pas important celui-ci peut sembler mieux:

form_params = {} 
['tid', 'qid', 'pri', 'sec', 'to_u', 'to_d', 'from', 'wl'].each do |v| 
    form_params[v] = eval(v) 
end 

Si ces noms sont en fait les méthodes que vous pouvez remplacer eval par le plus rapide send:

form_params[v] = send(v.to_sym) 

(mise à jour) Une alternative (et plus élégante) en utilisant inject:

form_params = ['tid', 'qid', 'pri', 'sec', 'to_u', 'to_d', 'from', 'wl'].inject({}) { |h, v| h[v] = send(v); h } 
0

J'ai créé une classe personnalisée appelée MoreOpenStruct pour traiter le manque d'esthétique de Hash, et en utilisant cette classe, votre exemple ressemblerait à ceci:

form_params = MoreOpenStruct.new 
form_params.tid = tid 
form_params.qid = qid 
form_params.pri = pri 
form_params.sec = sec 
form_params.to_u = to_u 
form_params.to_d = to_d 
form_params.from = from 
form_params.wl = wl 

form_params_hash = form_params._to_hash 
    #=> { :tid => tid, :qid => qid, etc } 

Si vous avez besoin littéraux de chaîne plutôt que des symboles comme la clé de votre Hash alors quelques tweaks supplémentaires sont nécessaires.

J'utilise ma classe struct personnalisée quand je veux lire/manipuler facilement des Hashes, mais si tout ce que vous faites est une affectation et que vous n'avez pas besoin d'analyser le hash au-delà, j'utiliserais la solution de Roger.

0

Les autres options serait de créer une classe en fonction Struct pour stocker ces valeurs dans Par exemple:.

FormParams = Struct.new(:tid, :qid, :pri, :sec, :to_u, :to_d, :from, :wl) 

Ensuite, vous seriez en mesure de l'instance de initialiser form_params dans une variété de façons:

form_params = FormParams.new(:tid => tid, :qid => qid, # etc ... 
form_params = FormParams.new(tid, qid, pri, sec, to_u, to_d, from, wl) 
form_params = FormParams.new 
form_params.tid = tid 
form_params.gid = gid 
# etc ... 
1

Et encore une autre forme, pour le rubis 1.9:

form_params = {tid: "tid", qid: "qid", ...} 
1
Hash[%w(tid qid pri sec to_u to_d from wl).collect{|x| [x,send(x)]}] 
0
a = %w(tid quid pri sec to_u to_d from wl) 
form_params = Hash[a.zip(a.collect {|v| send(v) })] 
Questions connexes