Получить значение переменной экземпляра по ее имени
В общем, как я могу получить ссылку на объект, имя которого у меня есть в строке?
Более конкретно, у меня есть список имен параметров (переменные-члены - создаются динамически, поэтому я не могу ссылаться на них напрямую).
Каждый параметр является объектом, который также имеет from_s
метод.
Я хочу сделать что-то вроде следующего (что, конечно, не работает...):
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 ответа
Самый идиоматический способ добиться этого:
some_object.instance_variable_get("@#{name}")
Там нет необходимости использовать +
или же intern
; Руби справится с этим просто отлично. Однако, если вы обнаруживаете, что достигли другого объекта и вытащили его ивар, есть достаточно хороший шанс, что вы нарушили инкапсуляцию.
Если вы явно хотите получить доступ к ивару, то вам нужно сделать его средством доступа. Учтите следующее:
class Computer
def new(cpus)
@cpus = cpus
end
end
В этом случае, если вы сделали Computer.new
, вы были бы вынуждены использовать instance_variable_get
добраться до @cpus
, Но если вы делаете это, вы, вероятно, имеете в виду для @cpus
быть публичным. Что вы должны сделать, это:
class Computer
attr_reader :cpus
end
Теперь вы можете сделать Computer.new(4).cpus
,
Обратите внимание, что вы можете открыть любой существующий класс и превратить приватный ивар в читателя. Поскольку метод доступа - это просто метод, вы можете сделать Computer.new(4).send(var_that_evaluates_to_cpus)
Чтобы получить переменную экземпляра из имени переменной экземпляра, выполните:
name = "paramName"
instance_variable_get(("@" + name).intern)
Это вернет значение переменной экземпляра @paramName