2011-10-19 14 views
16

¿Qué @ reposar en el siguiente código Ruby:lo que no @ reposar en un nombre de función Rubí

module TestRocket 
    extend Module.new { attr_accessor :out } 

    def _test(a, b); send((call rescue()) ? a : b); end 

    def [email protected]; _show _test :_pass, :_fail end 
    def [email protected]; _show _test :_fail, :_pass end 
    def [email protected]; _show _pend;    end 
    def [email protected]; _show _desc;    end 

    def _show(r); (TestRocket.out || $>) << r; r end 
    def _pass; "  OK\n"; end 
    def _fail; " FAIL @ #{source_location * ':'}\n"; end 
    def _pend; "PENDING '#{call}' @ #{source_location * ':'}\n"; end 
    def _desc; " FIRE '#{call}'!\n"; end 
end 

Proc.send :include, TestRocket 

A continuación, este se utiliza como:

+-> { Die.new(2) } 
--> { raise } 
+-> { 2 + 2 == 4 } 

¿Cómo funciona @ convertirse en ' -> 'en el nombre de la función?

+0

buena pregunta. Nunca he visto esto Pero si intentas ejecutar '+ -> {2 + 2 == 4}' sin él, obtienes un error 'NoMethodError: método indefinido' + @ 'para # '. Así que supongo que este es un método mágico de ruby ​​1.9 –

+0

El repositorio de TestRocket es https://github.com/peterc/testrocket –

Respuesta

15

Los nombres de los métodos para los cuatro operadores unarios +, -, ~, y ! son [email protected], [email protected], [email protected], y [email protected]. Así que las definiciones de métodos divertidos:

def [email protected]; _show _test :_pass, :_fail end 
def [email protected]; _show _test :_fail, :_pass end 
def [email protected]; _show _pend;    end 
def [email protected]; _show _desc;    end 

solo definen sobrecargas para esos cuatro operadores únicos. Entonces TestRocket se parchea en la clase Proc usando Proc.send :include, TestRocket.

Este:

-> { Die.new(2) } 

es simplemente una definición lambda y otra forma de escribir lambda { Die.new(2) }. Luego, con TestRocket parcheado en Proc podemos decir esto:

+-> { Die.new(2) } 
# + lambda { Die.new(2) } 

y se ejecutará este método:

def [email protected]; _show _test :_pass, :_fail end 

como un método de instancia en que lambda.

Parece un poco un abuso de la sobrecarga del operador unario para "inventar" algo que se ve como los operadores -->, ~->, ... nuevos.

Cuestiones relacionadas