47 votos

¿Cuándo es mejor utilizar una estructura en lugar de un Hash en Ruby?

Una estructura de Ruby permite una instancia generar un conjunto de descriptores de acceso:

# Create a structure named by its constant
Customer = Struct.new(:name, :address)     #=> Customer
Customer.new("Dave", "123 Main")           #=> #<Customer name="Dave", address="123 Main">

Esto parece conveniente y potente, sin embargo, algo muy similar hace un Hash:

Customer = {:name => "Dave", :address => "123 Main"}

¿Cuáles son las situaciones del mundo real donde preferiría una estructura (y por qué), y cuáles son las advertencias o trampas en la elección de uno sobre el otro.

22voto

Book Of Zeus Puntos 116

Personalmente yo uso un struct en los casos cuando quiero hacer un trozo de la ley de datos como una colección de datos en lugar de acoplamiento flexible en virtud de un Hash.

Por ejemplo, he hecho un script que descarga videos de Youtube y no tengo una estructura para representar un Video y para comprobar si todos los datos están en su lugar:


Video = Struct.new(:title, :video_id, :id) do
  def to_s
    "http://youtube.com/get_video.php?t=#{id}&video_id=#{video_id}&fmt=18"
  end

  def empty?
    @title.nil? and @video_id.nil? and @id.nil?
  end
end

Más tarde, en mi código tengo un bucle que va a través de todas las filas en los videos de la fuente HTML de la página hasta empty? no devolver true.

Otro ejemplo que he visto es el de James Edward Gray IIs clase de configuración que utiliza OpenStruct agregar fácilmente la configuración de las variables de carga desde un archivo externo:

#!/usr/bin/env ruby -wKU

require "ostruct"

module Config
  module_function

  def load_config_file(path)
    eval <<-END_CONFIG
    config = OpenStruct.new
    #{File.read(path)}
    config
    END_CONFIG
  end
end

# configuration_file.rb
config.db = File.join(ENV['HOME'], '.cool-program.db')
config.user = ENV['USER']

# Usage:
Config = Config.load_config('configuration_file.rb')
Config.db   # => /home/ba/.cool-program.db
Config.user # => ba
Config.non_existant # => Nil

La diferencia entre Struct y OpenStruct es que Struct sólo responde a los atributos que hemos establecido, OpenStruct responde a cualquier conjunto de atributos - pero aquellos que no tienen valor establecido volverá Nil

10voto

JDonner Puntos 187

Una estructura tiene la característica de que puede obtener en sus elementos por índice, así como por su nombre:

irb(main):004:0> Person = Struct.new(:name, :age)
=> Person
irb(main):005:0> p = Person.new("fred", 26)
=> #
irb(main):006:0> p[0]
=> "fred"
irb(main):007:0> p[1]
=> 26
irb(main):008:0> p.name
=> "fred"
irb(main):009:0> p.age
=> 26

que a veces es útil.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X