2012-03-19 2 views
2

У меня есть два класса, и я хочу скопировать все методы из одного класса в другой. Некоторые методы не будут иметь аргументов, у некоторых будут аргументы, а некоторые будут иметь хеши в качестве аргументов. И я никогда не знаю заранее, какие будут. Поэтому я создал этот код, пока не понял, что он не учитывает аргументы. Есть ли способ получить список методов из класса, а затем клонировать их точно в другой класс?Скопировать все методы из одного класса в другой на лету

def partial(cls) 
    cls.instance_methods(false).each do |method_name| 
    define_method(method_name) do 
     cls.new.method(method_name.to_sym).call 
    end 
    end 
end 

методы создаются на лету, используя define_method в первом классе, так что я не могу просто использовать включаемый. Вышеприведенный код содержит cls, затем он находит все методы экземпляра, которые фактически записаны в этом классе, а не наследуемые, а затем создает новый метод с тем же именем. Когда этот метод вызывается, он фактически вызывает другой класс с его методом с тем же именем. Это прекрасно работает, если у меня нет аргументов. У меня была проверка состояния, чтобы увидеть, есть ли у нее аргументы, а затем он вызвал метод с аргументами, но он не очень хорошо обрабатывал хэши. Он сделал хэш как массив аргументов, чего я не хотел.

Мне было интересно, был ли простой способ буквально сказать: «Эй, вы знаете этот метод, что бы это ни было, буквально делайте то же самое для этого другого класса».

+0

Я смущен тем, что вы хотите сделать. Вы говорите о методах экземпляра, но затем вы говорите: «вызывает другой класс с его методом с тем же именем». Это не сработает, если вы не отслеживаете состояние другого класса. – AShelly

ответ

0

Если все методы идентичны, почему бы просто не определить их в общем модуле, который вы включаете в оба класса? Вы упоминаете не используется, так как включают в себя методы динамически определены, но это не означает, что они не будут найдены, когда вы подмешать модуль:

module Foo 
    def self.make_an_example_method(name) 
    define_method(name) do |*args| 
     puts "I am #{name} called with (#{args.inspect})" 
    end 
    end 
end 

class A 
    include Foo 
end 

class B 
    include Foo 
end 

Foo.make_an_example_method(:example) 
Foo.make_an_example_method(:dynamic) 

A.new.example   # => I am example called with ([]) 
B.new.dynamic(1,2,3) # => I am dynamic called with ([1, 2, 3]) 
2

Вы также можете try DelegateClass:

class NamedArray < DelegateClass(Array) 
    def initialize n 
    @name = n 
    super(Array.new) 
    end 
    def sayName 
    "My name is #{@name}" 
    end 
end 
Смежные вопросы