what validar update recorrer rails metodos ruby hash struct

update - validar hash ruby



¿Cuándo usar Struct en lugar de Hash en Ruby? (5)

No tengo mucha experiencia en programación. Pero, para mí, Struct parece algo similar a Hash.

  • ¿Qué puede hacer Struct?
  • ¿Hay algo que Struct pueda hacer, eso Hash no puede hacer?

Después de googlear, el concepto de Struct es importante en C, pero no sé mucho sobre C.


De la documentación de Struct :

A Struct es una forma conveniente de agrupar una serie de atributos, utilizando métodos de acceso, sin tener que escribir una clase explícita.

Por otro lado, un Hash :

Un hash es una colección de pares clave-valor. Es similar a una matriz, excepto que la indexación se realiza mediante claves arbitrarias de cualquier tipo de objeto, no como un índice entero. El orden en el que recorre un hash por clave o valor puede parecer arbitrario, y generalmente no estará en el orden de inserción.

La principal diferencia es cómo accede a sus datos.

ruby-1.9.1-p378 > Point = Struct.new(:x, :y) => Point ruby-1.9.1-p378 > p = Point.new(4,5) => #<struct Point x=4, y=5> ruby-1.9.1-p378 > p.x => 4 ruby-1.9.1-p378 > p.y => 5 ruby-1.9.1-p378 > p = {:x => 4, :y => 5} => {:x=>4, :y=>5} ruby-1.9.1-p378 > p.x NoMethodError: undefined method `x'' for {:x=>4, :y=>5}:Hash from (irb):7 from /Users/mr/.rvm/rubies/ruby-1.9.1-p378/bin/irb:17:in `<main>'' ruby-1.9.1-p378 > p[:x] => 4 ruby-1.9.1-p378 > p[:y] => 5

En resumen, crearías un nuevo Struct cuando quieras una clase que sea una estructura de "datos antiguos simples" (opcionalmente con la intención de ampliarla con más métodos), y usarías un Hash cuando no necesites un tipo formal en absoluto.


Las estructuras difieren del uso de hashmaps de las siguientes maneras (además de cómo se ve el código):

  • Una estructura tiene un conjunto fijo de atributos, mientras agrega nuevas claves a un hash.
  • Llamar a un atributo que no existe en una instancia de una estructura provocará un NoMethodError, mientras que obtener el valor para una clave no existente de un hash simplemente devolverá cero.
  • Dos instancias de diferentes estructuras nunca serán iguales, incluso si las estructuras tienen los mismos atributos y las instancias tienen los mismos valores (es decir, Struct.new(:x).new(42) == Struct.new(:x).new(42) es falso, mientras que Foo = Struct.new(:x); Foo.new(42)==Foo.new(42) es verdadero).
  • El método to_a para structs devuelve una matriz de valores, mientras que to_a en un hash obtiene una matriz de pares clave-valor (donde "pair" significa "matriz de dos elementos")
  • Si Foo = Struct.new(:x, :y, :z) puede hacer Foo.new(1,2,3) para crear una instancia de Foo sin tener que deletrear los nombres de los atributos.

Entonces, para responder la pregunta: cuando quiera modelar objetos con un conjunto conocido de atributos, use structs. Cuando desee modelar el uso arbitrario de los hashmaps (por ejemplo, contar la frecuencia con que cada palabra aparece en una cadena o asignar apodos a los nombres completos, etc. definitivamente no son trabajos para una estructura, mientras que modelar a una persona con un nombre, una edad y una dirección sería un ajuste perfecto para Person = Struct.new(name, age, address) ).

Como nota al margen: las estructuras C tienen poco o nada que ver con las estructuras de rubí, así que no te dejes confundir por eso.


Otra diferencia principal es que puede agregar métodos de comportamiento a un Struct.

Customer = Struct.new(:name, :address) do def greeting; "Hello #{name}!" ; end end Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"


Sé que esta pregunta fue casi bien respondida, pero sorprendentemente nadie ha hablado de una de las mayores diferencias y los beneficios reales de Struct . Y supongo que es por eso que alguien sigue preguntando .

Entiendo las diferencias, pero ¿cuál es la ventaja real de usar Struct sobre un Hash, cuando un Hash puede hacer lo mismo y es más fácil de tratar? Parece que las estructuras son superfluas.

Struct es más rápido .

require ''benchmark'' Benchmark.bm 10 do |bench| bench.report "Hash: " do 50_000_000.times do { name: "John Smith", age: 45 } end end bench.report "Struct: " do klass = Struct.new(:name, :age) 50_000_000.times do klass.new("John Smith", 45) end end end # ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32]. # user system total real # Hash: 22.340000 0.016000 22.356000 ( 24.260674) # Struct: 12.979000 0.000000 12.979000 ( 14.095455) # ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin11.0] # # user system total real # Hash: 31.980000 0.060000 32.040000 ( 32.039914) # Struct: 16.880000 0.010000 16.890000 ( 16.886061)


Si vas a encapsular los datos, entonces un Hash (o una matriz de Hashes) están bien. Si planea que los datos manipulen o interactúen con otros datos, entonces Struct puede abrir algunas posibilidades interesantes:

Point = Struct.new(:x, :y) point_a = Point.new(0,0) point_b = Point.new(2,3) class Point def distance_to another_point Math.sqrt((self.x - another_point.x)**2 + (self.y - another_point.y)**2) end end puts point_a.distance_to point_b