2010-04-21 7 views
14

Me preguntaba cómo acceder a una función global fn en ruby ​​de una clase que también definió un método fn. He hecho una solución mediante un alias a la función de este modo:Cómo acceder a una función global (sombreada) en ruby ​​

 
def fn 
end 

class Bar 
    alias global_fn fn 
    def fn 
     # how to access the global fn here without the alias 
     global_fn 
    end 
end 

estoy buscando algo en la línea de C++ 's :: para acceder alcance global, pero me parece que no puede encontrar ninguna información al respecto. Supongo que no sé específicamente lo que estoy buscando.

Respuesta

16

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.

+0

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? –

+0

@yngvedh, exactamente. Se romperá de la misma manera. El enfoque más general de IMO es usar la segunda solución. – horseyguy

+0

@banister, y no hay otra manera de lograr eso? Estoy pensando en algo más sintácticamente agradable, como Object :: fn de C++. –

Cuestiones relacionadas