Получить значение переменной экземпляра с заданным именем


В общем, как я могу получить ссылку на объект, имя которого у меня в строке?

более конкретно, у меня есть список имен параметров (переменные - члены, построенные динамически, поэтому я не могу ссылаться на них напрямую).

каждый параметр является объектом, который также имеет 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 87

2 ответа:

самый идиоматический способ добиться этого:

some_object.instance_variable_get("@#{name}")

нет необходимости использовать + или intern; Руби справится с этим просто отлично. Однако, если вы обнаружите, что достигаете другого объекта и вытаскиваете его ivar, есть достаточно хороший шанс, что вы нарушили инкапсуляцию.

если вы явно хотите получить доступ к ivar, правильно сделать это, чтобы сделать его аксессором. Рассмотрим следующее:

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