Ruby - динамично добавьте свойство к классу (во времени выполнения) [дубликат]

10
задан zanona 8 August 2012 в 08:56
поделиться

4 ответа

Подход method_missing будет работать, но если вы собираетесь использовать аксессоры много позже добавляя их, вы также можете добавить их как настоящие методы, например:

class Client
  def add_attrs(attrs)
    attrs.each do |var, value|
      class_eval { attr_accessor var }
      instance_variable_set "@#{var}", value
    end
  end
end

Это заставит их работать как обычные переменные экземпляра, но только для одного клиента .

15
ответ дан 3 December 2019 в 21:19
поделиться

Я думаю, что лучшим решением будет mckeed

Но вот еще одна идея, над которой стоит подумать. Вы можете создать подкласс OpenStruct, если хотите:

require 'ostruct'

class Client < OpenStruct
  def initialize args = {}
    super
  end
  def add_methods( args = Hash.new )
    args.each do |name,initial_value|
      new_ostruct_member name
      send "#{name}=" , initial_value
    end
  end
end

client = Client.new :login => 'user', :password => 'xxxxx'
client.add_methods :swift_bic=>"XXXX", :account_name=>"XXXX", :iban=>"XXXX" , :to_s => 5
client # => #<Client login="user", password="xxxxx", swift_bic="XXXX", account_name="XXXX", iban="XXXX", to_s=5>

client.swift_bic      # => "XXXX"
client.account_name   # => "XXXX"

Однако есть две проблемы с этим решением. OpenStruct использует method_missing, поэтому, если вы определяете такой метод, как id, в 1.8 он найдет object_id вместо того, чтобы находить ваш метод.

Вторая проблема заключается в том, что он использует некоторые частные знания о том, как реализован OpenStruct. Так что в будущем его можно будет изменить, взломав этот код (для записи я проверил 1.8.7 - 1.9.2, и это было совместимо)

2
ответ дан 3 December 2019 в 21:19
поделиться

Посмотрите на Object.method_missing. Эта функция будет вызываться всякий раз, когда к вашему объекту обращаются с методом, который не определен. Вы можете определить эту функцию и использовать ее для проверки неопределенного метода на имя одного из ваших хэш-значений. Если оно совпадает, возвращается хэш-значение.

Вы также можете определить свою собственную функцию inspect и сгенерировать выходную строку, содержащую то, что вы хотите, чтобы она содержала.

0
ответ дан 3 December 2019 в 21:19
поделиться

Я собираюсь порекомендовать для этого не использовать method_missing - это создает множество «волшебных» функций, которые невозможно легко задокументировать или понять без проработки method_missing тело. Вместо этого изучите OpenStruct, как предлагается - вы даже можете создать свой собственный класс, наследующий от него, например:

class Client < OpenStruct
  ...
end

, и вы сможете инициализировать клиента с любым полученным хешем.

0
ответ дан 3 December 2019 в 21:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: