J'ai un hash
foo = {'bar'=>'baz'}
Je voudrais appeler foo.bar #=> 'baz'
Ma motivation réécrit une requête Activerecord dans une requête SQL brute (utilisant le modèle # Find_By_SQL). Cela renvoie un hachage avec les valeurs de clause Select en tant que touches. Cependant, mon code existant repose sur l'objet.Method STOT NOTION. Je voudrais faire une réécriture de code minimal. Merci.
Edit: Il semble que Lua a cette fonctionnalité:
point = { x = 10, y = 20 } -- Create new table
print(point["x"]) -- Prints 10
print(point.x) -- Has exactly the same meaning as line above
>> require 'ostruct'
=> []
>> foo = {'bar'=>'baz'}
=> {"bar"=>"baz"}
>> foo_obj = OpenStruct.new foo
=> #<OpenStruct bar="baz">
>> foo_obj.bar
=> "baz"
>>
Ce que vous cherchez est appelé OpenStruct . Cela fait partie de la bibliothèque standard.
Une bonne solution:
class Hash
def method_missing(method, *opts)
m = method.to_s
if self.has_key?(m)
return self[m]
elsif self.has_key?(m.to_sym)
return self[m.to_sym]
end
super
end
end
Remarque: cette implémentation n'a qu'un bug connu:
x = { 'test' => 'aValue', :test => 'bar'}
x.test # => 'aValue'
Si vous préférez des recherches de symboles plutôt que des recherches de chaîne, alors échangez les deux "si" condition
Plutôt que de copier toutes les choses hors du hachage, vous pouvez simplement ajouter un comportement au hasch pour faire des recherches.
Si vous ajoutez cette définition, vous étendez hachage pour gérer toutes les méthodes inconnues telles que les recherches de hachage:
class Hash
def method_missing(n)
self[n.to_s]
end
end
Gardez à l'esprit que cela signifie que vous ne verrez jamais des erreurs si vous appelez la mauvaise méthode sur HASH - vous obtiendrez tout ce que la recherche de hachage correspondante reviendrait.
Vous pouvez réduire considérablement les problèmes de débogage que cela peut causer par uniquement la mise sur un hachage spécifique - ou autant de halés que vous avez besoin:
a={'foo'=>5, 'goo'=>6}
def a.method_missing(n)
self[n.to_s]
end
L'autre observation est que lorsque method_missing
est appelé par le système, cela vous donne un argument Symbol
. Mon code le convertit en un String
. Si vos clés de hachage ne sont pas des chaînes, ce code ne retournera jamais ces valeurs - si vous touchez des symboles au lieu de cordes, remplacez simplement n
pour n.to_s
dessus.
Il y a quelques pierres précieuses pour cela. Il y a mon joyau récent, hash_dot , et quelques autres pierres précieuses avec des noms similaires que j'ai découverts, alors que j'ai publié le mien sur des rubisgèvres, y compris dot_hash .
Hashdot permet la syntaxe de notation DOT, tout en adressant toujours les préoccupations concernant les nométreurs adressées par @AVDI. Il est plus rapide et plus traversable qu'un objet créé avec openStruct.
require 'hash_dot'
a = {b: {c: {d: 1}}}.to_dot
a.b.c.d => 1
require 'open_struct'
os = OpenStruct.new(a)
os.b => {c: {d: 1}}
os.b.c.d => NoMethodError
Il maintient également le comportement attendu lorsque les non-méthodes sont appelées.
a.non_method => NoMethodError
N'hésitez pas à soumettre des améliorations ou des bugs à Hashdot.