Можно копировать методы из одного класса в другой, но есть серьезное предостережение: целевой класс должен быть kind_of?исходный класс или источник должен быть модулем.Это ограничение частично задокументировано в документации для UnboundMethod # bind , но чтобы увидеть исключение модуля, вам нужно взглянуть на исходный код метода. Этот ответ содержит дополнительные обсуждения по теме.
Вот пример:
module A
def say_hello
puts "Hello"
end
end
class B
define_method(:say_hello, A.instance_method(:say_hello))
end
b = B.new
b.say_hello
=> Hello
Это также будет работать, если A
был классом и B
был класс, унаследованный от A
.Но в этом случае вы уже получили бы метод с помощью наследования, поэтому я лично не вижу его использования.
Единственная ситуация, в которой я нашел этот шаблон полезным, - это проектирование DSL с использованием объектов, которыенаследовать от BasicObject
.Поскольку BasicObject
не include Kernel
, как Object
, у вас нет простого доступа ко многим полезным методам, таким как #instance_variables
или даже #class
.Но вы можете скопировать их по отдельности из ядра в ваш класс:
class Foo < BasicObject
define_method(:class, ::Kernel.instance_method(:class))
end
f = Foo.new
puts f.class
=> Foo