получить значение переменной динамически - PullRequest
8 голосов
/ 02 апреля 2011

У меня есть следующий класс

class User
  attr_accessor :name, :age, :address

  def initialize()
    self.name = "new user"
    self.age = 19
    self.address = "address" 
  end  


end

Что я хочу, если у меня есть метод для получения назначенных значений для атрибутов. Значит, у меня есть другой метод, чтобы получить все имена методов внутри вышеуказанного класса

methods = self.public_methods(all = false)

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

Пример:

когда я передаю 'name' в качестве имени метода, я могу получить 'new user' в качестве значения

надеюсь, я прояснил свой вопрос, заранее спасибо

** Обратите внимание, я должен использовать этот способ, поскольку у моего класса так много атрибутов, и у него так много унаследованных классов. Таким образом, доступ к каждому атрибуту в отдельности невозможен: D

1 Ответ

14 голосов
/ 02 апреля 2011

Вот для чего send:

user = User.new
user.name        # => "new user"
user.send(:name) # => "new user"

getters = user.public_methods(false).reject { |m| m =~ /=$/ }
getters.each { |m| puts user.send(m) }

Использование instance_variable_get - еще один вариант, если у вас нет метода доступа:

user.instance_variable_get(:@name) # => "new user"

Использование public_methodsполучить список атрибутов может быть опасно, в зависимости от того, как вы определяете, какие методы вызывать.Вместо этого вы можете создать свой собственный метод класса, который одновременно определяет метод доступа и сохраняет имя атрибута для будущего использования:

class User
  class << self
    attr_reader :fields

    def field (*names)
      names.flatten.each do |name|
        attr_accessor name
        (@fields ||= []) << name
      end
    end
  end

  field :name
  field :age
  field :address
end

user = User.new
user.name    = "Me"
user.age     = 22
user.address = "1234"

user.class.fields.each do |field|
  puts user.send(field)
end
...