2011-04-20 22 views
6

Estoy tratando de encontrar una forma de que pueda anular un método, hacer algo y luego revertir sin dejar ningún artefacto.ruby ​​- anula el método y luego invierte

Lo he implementado usando mocha, pero obviamente esto no va a volar en una aplicación de producción. Tenga en cuenta que el nuevo método tiene parámetros y el anterior no.

Ejemplo de la siguiente manera

require 'rubygems' 
require 'mocha' 

class Example 

    def to_something 
    self.stubs(:attribs => other(1)) 
    r = attribs_caller 
    self.unstub(:attribs) 
    r 
    end 

    def other(int) 
    {"other" => int } 
    end 

    def attribs_caller 
    attribs 
    end 

    def attribs 
    {"this" => 1 } 
    end 

end 

a1 = Example.new 

puts a1.attribs_caller #=> this1 
puts a1.to_something #=> other1 
puts a1.attribs_caller #=> this1 

Respuesta

2

Otra manera de hacer eso, sin crear un método adicional, es la siguiente:

class Foo 
    def bar 
    :old_method 
    end 
end 

Foo.new.foo # => :old_method 

$old_method = Foo.new.method(:bar) 

class Foo 
    def bar 
    :new_method 
    end 
end 

Foo.new.foo # => :new_method 

class Foo 
    define_method($old_method.name, &$old_method) 
end 

Foo.new.foo # => :old_method 

creo que esto es mejor que usar un método de alias . En Ruby los métodos son, también, objetos. Solo tomo la referencia del objeto antes de destruir la asociación del objeto (el método) con la clase. Después de agregar el mismo método. También funciona si usa la palabra clave undef para eliminar el método de la clase. Lo malo es que debes tener un objeto de la clase para tomar la referencia del método.

7
class String 
    alias orig_reverse reverse 
    def reverse(n) 
    'fooled you. '*n 
    end 
end 

puts "ab".reverse(2) 
#=> fooled you fooled you 

# clean up: 
class String 
    alias reverse orig_reverse 
    remove_method(:orig_reverse) 
end 

puts "ab".reverse #=> ba 
+0

bueno, un problema con esto es el hecho de que el nuevo método es dinámico y requiere algunos parámetros. Sin embargo, podría definir este método dinámicamente. Actualicé el ejemplo para reflejar esto. – stellard

+0

Parece que el orden correcto de los parámetros es 'alias alias_nombre original_nombre', no al revés ... – vemv

Cuestiones relacionadas