En el nivel superior, un def
agrega un método privado al Object
.
puedo pensar en tres maneras de obtener la función de nivel superior:
(1) Use send
para invocar el método privado en Object
sí (sólo funciona si el método no es un mutador desde Object
será el receptor)
Object.send(:fn)
(2) Obtener una instancia Method
del método de nivel superior y se une a la instancia que desea invocar en:
class Bar
def fn
Object.instance_method(:fn).bind(self).call
end
end
(3) Utilice super
(no asume ninguna clase de super de Bar
debajo Object
redefinir la función)
class Bar
def fn
super
end
end
ACTUALIZACIÓN:
Puesto que la solución (2) es el preferible (en mi opinión) que puede tratar de mejorar la sintaxis mediante la definición de un método de utilidad en Object
llamada 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
Utilice el siguiente aspecto:
class Bar
def fn
super_method Object, :fn
end
end
Donde el primer argumento de super_method
debe ser una superclase válida de Bar
, el segundo argumento del método que desea invocar, y todos los argumentos restantes (si los hay) se pasó a lo largo como parámetros al método seleccionado.
No sabía que los métodos globales realmente se agregan a Object. ¿Esto significa que mi enfoque de alias, como su súper enfoque también se romperá también si Bar tiene una superclase que también define fn? –
@yngvedh, exactamente. Se romperá de la misma manera. El enfoque más general de IMO es usar la segunda solución. – horseyguy
@banister, y no hay otra manera de lograr eso? Estoy pensando en algo más sintácticamente agradable, como Object :: fn de C++. –