relaciones programacion privados orientada objetos metodos herencia entre clases clase atributos ruby class time override alias

ruby - privados - relaciones entre clases programacion orientada a objetos



¿Cómo puede uno, sin herencia, anular un método de clase y llamar al original desde el nuevo método? (4)

Esto es un poco difícil de manejar algunas veces, pero necesita abrir la "clase propia" que es el singleton asociado a un objeto de clase específico. la sintaxis para esto es clase << self do ... end.

class Time alias :old_strftime :strftime def strftime puts "got here" old_strftime end end class Time class << self alias :old_now :now def now puts "got here too" old_now end end end t = Time.now puts t.strftime

Encontré una fuente que Time.strftime éxito Time.strftime esta manera:

class Time alias :old_strftime :strftime def strftime #do something old_strftime end end

El problema es que strftime es un método de instancia. Necesito anular Time.now - un método de clase - de tal manera que cualquier persona que llama obtenga mi nuevo método, mientras que el nuevo método todavía llama al método .now original. Miré alias_method y no tuve éxito.


Los métodos de clase son solo métodos. Recomiendo mucho no hacerlo, pero tiene dos opciones equivalentes:

class Time class << self alias_method :old_time_now, :now def now my_now = old_time_now # new code my_now end end end class << Time alias_method :old_time_now, :now def now my_now = old_time_now # new code my_now end end


Si necesita anularlo para fines de prueba (la razón por la que normalmente deseo anular Time.now), los marcos de burla / borrado de Ruby lo harán por usted fácilmente. Por ejemplo, con RSpec (que usa flexmock):

Time.stub!(:now).and_return(Time.mktime(1970,1,1))

Por cierto, recomiendo evitar la necesidad de eliminar Time.now dando a sus clases un reloj anulable:

class Foo def initialize(clock=Time) @clock = clock end def do_something time = @clock.now # ... end end


He estado tratando de descubrir cómo anular un método de instancia usando módulos.

module Mo def self.included(base) base.instance_eval do alias :old_time_now :now def now my_now = old_time_now puts ''overrided now'' # new code my_now end end end end Time.send(:include, Mo) unless Time.include?(Mo) > Time.now overrided now => Mon Aug 02 23:12:31 -0500 2010