Как я могу добавить новые атрибуты для конкретного экземпляра? - PullRequest
2 голосов
/ 10 марта 2011

Как добавить новые атрибуты в конкретный экземпляр?

Например, здесь я хочу добавить методы attr_acessors к атрибутам "m1", "m2" в объекте e1 и "m4" .. "m6" к e2

e1=Element.new("e1",["m1","m2"])
e2=Element.new("e2",["m4","m5","m6"])
e1.m1 = "try"
puts e2.m4

Чтобы разрешить это:

class Element
  attr_accessor :name
  def initialize name,meths=[]
    @name=name
    meths.each do |m|
      #?? 
    end
  end
end

Ответы [ 3 ]

2 голосов
/ 10 марта 2011

Почему бы не использовать вместо этого простой OpenStruct?

require 'ostruct'
e1 = OpenStruct.new
e1.m1 = 'try'

В качестве альтернативы, вы можете добавить атрибут к любому объекту, используя:

a.instance_eval('def m2; @m2; end; def m2=(x); @m2=x;end')

Если вы хотите добавить атрибуты ко всем экземплярамКонкретный класс вы также можете:

a.class.instance_eval('attr_accessor :mmm')
1 голос
/ 12 марта 2011

Вот более простое решение:

methods.each do |method|
 class << self
  attr_accessor method
 end
end

Таким образом, вы избавляетесь от дополнительного определения метода и class_eval, потому что class << self уже помещает вас в область действия собственного класса, где вы добавляете одноэлементные методы.

1 голос
/ 10 марта 2011

Попробуйте:

meths.each do |m|
  singleton_class().class_eval do
    attr_accessor m
  end
end

, где метод singleton_class() определяется как:

def singleton_class
  class << self
    self
  end
end

(вы, вероятно, хотите сделать его закрытым).

Это создаст методы доступа только на конкретном экземпляре, а не на классе Element.

...