2013-11-25 3 views
0

Я довольно новичок в метапрограмме Ruby. Я пытаюсь написать код, который генерирует «dup» для класса при его создании, используя список полей, которые должны быть переданы в конструктор. Тем не менее, я не могу понять, как получить доступ к имени класса, который я создаю, пока я его создаю.Ruby metaprogramming: доступ к названию класса

Так, например, если у меня был этот код:

class Example 
    make_dup :name, :value 
    attr_accessor :name, :value 

    def initialize(name,value) 
    @name, @value = name, value 
    end 
end 

Я хочу, чтобы это создать метод:

def dup 
    Example.new(name,value) 
end 

Я просто застрять на том, как было бы выяснить, вставить Example.

+3

Я не понимаю, что вы подразумеваете под созданием метода 'dup' для класса, учитывая, что он наследует' Class # dup'. Что касается получения объекта класса, 'self' равно' Example', как только «class Example» анализируется. Вы можете проверить это с помощью 'puts'. –

+0

Вы ответили на мои вопросы. Благодарю. –

ответ

0

Может быть, вы можете реализовать это следующим образом: результат

module MyDup 
    def make_dup(*args) 
    define_method(:my_dup) do 
     obj = self.class.new(nil, nil) 
     args.each do |arg| 
     obj.send(arg.to_s + "=", self.send(arg)) 
     end 
     obj 
    end 
    end 
end 

class Example 
    extend MyDup 
    make_dup :name, :value 
    attr_accessor :name, :value 

    def initialize(name,value) 
    @name, @value = name, value 
    end 
end 

e = Example.new("John", 30) 
p e 

d = e.my_dup 
p d 

Execution следующим образом:

#<Example:0x000000022325d8 @name="John", @value=30> 
#<Example:0x00000002232358 @name="John", @value=30> 
1

Обратите внимание, что все классы имеют встроенные dup и clone методов. Вы можете настроить то, что происходит в них, добавляя initialize_copy метод, например:

class Foo 
    attr_accessor :bar 
    def initialize_copy(orig) 
    super 
    @bar = @bar.dup 
    end 
end 

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

class Foo 
    def p_class 
    p self.class  # Foo.new.p_class => Foo  ; self is *a* `Foo' 
    end 

    def self.p_class 
    p self.class  # Foo.p_class  => Class ; self *is* `Foo' 
    end 
end 
+0

не нравится, что вам нужны дополнительные очки, но это действительно хороший ответ – iGbanam

Смежные вопросы