ruby grape example
hash[''key''] a hash.key en Ruby (5)
En lugar de copiar todas las cosas del hash, puede agregar algo de comportamiento a Hash para realizar búsquedas.
Si agrega esta definición, extienda Hash para manejar todos los métodos desconocidos como búsquedas de hash:
class Hash
def method_missing(n)
self[n.to_s]
end
end
Ten en cuenta que esto significa que nunca verás errores si llamas al método incorrecto en hash; obtendrás lo que devuelva la búsqueda hash correspondiente.
Puede reducir enormemente los problemas de depuración que esto puede causar al poner el método solo en un hash específico o tantos hashes como necesite:
a={''foo''=>5, ''goo''=>6}
def a.method_missing(n)
self[n.to_s]
end
La otra observación es que cuando el sistema llama a method_missing
, le da un argumento de Symbol
. Mi código lo convirtió en una String
. Si sus claves hash no son cadenas, este código nunca devolverá esos valores; si n.to_s
por símbolos en lugar de cadenas, simplemente sustituya n
por n.to_s
arriba.
Tengo aa hash
foo = {''bar''=>''baz''}
Me gustaría llamar a foo.bar #=> ''baz''
Mi motivación es reescribir una consulta activerecord en una consulta sql en bruto (usando el modelo # find_by_sql). Esto devuelve un hash con los valores de la cláusula SELECT como claves. Sin embargo, mi código existente se basa en la notación de puntos object.method. Me gustaría hacer una mínima reescritura de código. Gracias.
Editar: parece que Lua tiene esta característica:
point = { x = 10, y = 20 } -- Create new table
print(point["x"]) -- Prints 10
print(point.x) -- Has exactly the same meaning as line above
Hay algunas gemas para esto. Allí está mi gema reciente, hash_dot y algunas gemas con nombres similares que descubrí cuando dot_hash el mío en RubyGems, incluido dot_hash .
HashDot permite la sintaxis de notación de puntos, al mismo tiempo que responde a las preocupaciones sobre NoMethodErrors abordadas por @avdi. Es más rápido y más transitable que un objeto creado con 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
También mantiene el comportamiento esperado cuando se llaman no métodos.
a.non_method => NoMethodError
Por favor, siéntase libre de enviar mejoras o errores a HashDot.
Lo que estás buscando se llama OpenStruct . Es parte de la biblioteca estándar.
Una buena solución:
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
Nota: esta implementación solo tiene un error conocido:
x = { ''test'' => ''aValue'', :test => ''bar''}
x.test # => ''aValue''
Si prefiere búsquedas de símbolos en lugar de búsquedas de cadenas, cambie las dos condiciones ''si''
>> require ''ostruct''
=> []
>> foo = {''bar''=>''baz''}
=> {"bar"=>"baz"}
>> foo_obj = OpenStruct.new foo
=> #<OpenStruct bar="baz">
>> foo_obj.bar
=> "baz"
>>