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

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

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

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

Другие вопросы по тегам