Obtener el valor de una variable de instancia con su nombre
En general, ¿cómo puedo obtener una referencia a un objeto cuyo nombre tengo en una cadena?
Más específicamente, tengo una lista de los nombres de los parámetros (las variables miembro - construidas dinámicamente por lo que no puedo hacer referencia a ellos directamente).
Cada parámetro es un objeto que también tiene un método from_s
.
Quiero hacer algo como lo siguiente (que por supuesto no funciona...):
define_method(:from_s) do | arg |
@ordered_parameter_names.each do | param |
instance_eval "field_ref = @#{param}"
field_ref.from_s(param)
end
end
2 answers
La forma más idiomática de lograr esto es:
some_object.instance_variable_get("@#{name}")
No hay necesidad de usar +
o intern
; Ruby manejará esto muy bien. Sin embargo, si te encuentras alcanzando otro objeto y sacando su ivar, hay una probabilidad razonablemente buena de que hayas roto la encapsulación.
Si desea acceder explícitamente a un ivar, lo correcto es convertirlo en un accessor. Considere lo siguiente:
class Computer
def new(cpus)
@cpus = cpus
end
end
En este caso, si lo hicieras Computer.new
, te verías forzado usar instance_variable_get
para llegar a @cpus
. Pero si estás haciendo esto, probablemente quieres decir que @cpus
sea público. Lo que debes hacer es:
class Computer
attr_reader :cpus
end
Ahora puedes hacer Computer.new(4).cpus
.
Tenga en cuenta que puede reabrir cualquier clase existente y convertir un ivar privado en un lector. Dado que un accessor es solo un método, puede hacer Computer.new(4).send(var_that_evaluates_to_cpus)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-06 20:42:16
Para obtener una variable de instancia del nombre de una variable de instancia, haga lo siguiente:
name = "paramName"
instance_variable_get(("@" + name).intern)
Esto devolverá el valor de la variable de instancia @paramName
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 14:52:36