ruby attr-accessor

Ruby: genera dinĂ¡micamente attribute_accessor



attr-accessor (3)

Podrías hacer un poco de meta-magia para resolver esto, usando method_missing:

class Event def method_missing(method_name, *args, &block) if instance_variable_names.include? "@#{method_name}" instance_variable_get "@#{method_name}" else super end end end

Lo que esto hará es permitir el acceso a las variables de instancia de objeto a través de la sintaxis de object.variable, si el objeto tiene esas variables definidas, sin recurrir a modificar la clase completa a través de attr_accessor.

Estoy intentando generar el attr_reader a partir de un hash (con hash anidado) para que refleje la creación de instancia_variable automáticamente.

Esto es lo que tengo hasta ahora:

data = {:@datetime => ''2011-11-23'', :@duration => ''90'', :@class => {:@price => ''£7'', :@level => ''all''}} class Event #attr_reader :datetime, :duration, :class, :price, :level def init(data, recursion) data.each do |name, value| if value.is_a? Hash init(value, recursion+1) else instance_variable_set(name, value) #bit missing: attr_accessor name.to_sym end end end

Pero no puedo encontrar una manera de hacerlo: (


attr_accessor es un método de clase y como tal debe invocarse en la clase. También es un método privado, por lo que necesita invocarlo en un contexto en el que el objeto de clase sea self .

Como ejemplo:

class C def foo self.class.instance_eval do attr_accessor :baz end end end

Después de crear una instancia de C y llamar a foo en esa instancia, esa instancia, y todas las instancias futuras, contendrán los métodos baz y baz= .


attr_accessor llamar al método de clase (privado) attr_accessor en la clase de Event :

self.class.send(:attr_accessor, name)

Te recomiendo agregar la @ en esta línea:

instance_variable_set("@#{name}", value)

Y no los uses en el hachís.

data = {:datetime => ''2011-11-23'', :duration => ''90'', :class => {:price => ''£7'', :level => ''all''}}