2015-04-25 2 views
-3

Я пытаюсь создать динамический класс споколения Динамического класса с атрибутами

dynamic_name = 'Person' 
Object.const_set(dynamic_name, Class.new {def init(attrs); end}) 

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

Person.class.module_eval { attr_accessor :name} 

Но можно поставить это непосредственно в метод init? Мне также необходимо установить ограничения для атрибута, например. имя атрибута, как указано выше, должно быть size > 0 и иметь возможность содержать символы в регулярных выражениях /^[A-Z]/

+0

Почему вы хотите это сделать? Чего вы пытаетесь достичь? – spickermann

+0

Мне нужно создать класс динамически с динамическим именем, а также атрибуты имеют динамические имена и типы! Разве это не способ сделать это? – wasp256

+0

Что такое 'size'? Что такое 'имя'? – sawa

ответ

1

attr_accessor :name нет ничего, кроме DSL аки синтаксического сахара, чтобы определить простые аксессор для name и name= методов. У него могут не быть никаких ограничений. Для определения ограничений следует идти с явным определением сеттер:

attr_reader :name 
def name= neu 
    raise ArgumentError.new("Name must be not empty") if neu.empty? 
    # additional constraints 
    @name = neu 
end 

Различная не связан с выше вопрос:

можно ли поставить это непосредственно в метод init?

Хотя я до сих пор не понимаю, что все это WooDoo плясать, можно:

def init *args 
    # native init stuff 
    self.class.define_method :name do 
    @name 
    end unless self.class.method_defined? :name 
    self.class.define_method :name= do |neu| 
    raise ArgumentError.new("Name must be not empty") if neu.empty? 
    # additional constraints 
    @name = neu 
    end unless self.class.method_defined? :name= 
end 

Надеется, что это помогает.

+0

Когда я использую блок кода ниже, я получаю сообщение об ошибке 'test.rb: 12: in 'init': private method 'define_method', вызываемый для Person: Class (NoMethodError) \t от test.rb: 36: in '

' ' – wasp256

+0

О, да. Это личное. Измените 'self.class.define_method (: name)' на 'self.class.send (: define_method,: name)'. – mudasobwa

+0

какой? все вызовы 'define_method'? – wasp256