На верхнем уровне def
добавляет приватный метод к Object
.
Я могу придумать три способа получить функцию верхнего уровня:
(1) Используйте send
для вызова приватного метода на самом Object
(работает, только если метод не является мутатором, так как Object
будет получателем)
Object.send(:fn)
(2) Получите Method
экземпляр метода верхнего уровня и привяжите его к экземпляру, для которого вы хотите его вызвать:
class Bar
def fn
Object.instance_method(:fn).bind(self).call
end
end
(3) Используйте super
(предполагается, что суперклассы Bar
ниже Object
не переопределяют функцию)
class Bar
def fn
super
end
end
UPDATE:
Поскольку решение (2) является предпочтительным (на мой взгляд), мы можем попытаться улучшить синтаксис, определив вспомогательный метод для Object
, называемый super_method
:
class Object
def super_method(base, meth, *args, &block)
if !self.kind_of?(base)
raise ArgumentError, "#{base} is not a superclass of #{self}"
end
base.instance_method(meth).bind(self).call(*args, &block)
end
end
Используйте как указано ниже:
class Bar
def fn
super_method Object, :fn
end
end
Если первый аргумент super_method
должен быть действительным суперклассом Bar
, второй аргумент - метод, который вы хотите вызвать, и все оставшиеся аргументы (если они есть) передаются в качестве параметров выбранному методу. 1037 *