Ответ 1
На верхнем уровне a 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
, второй аргумент - метод, который вы хотите вызвать, и все остальные аргументы (если они есть) передаются как параметры выбранного метода.