Ganchos/Hooks: Interviniendo en el Momento en que un Objeto es Creado

En esta sección se muestra una forma de intervenir en el momento en que un objeto es creado. El ejemplo consiste en que queremos añadirle a todo objeto un atributo timestamp que indica su fecha de creación. Se hace abriendo la clase Object y añadiéndole el atributo:

         class Object
           attr_accessor :timestamp
         end
Ahora bien, el método new es un método de clase, (Tutu.new) es un metodo de instancia de la clase Class:
>> Class.instance_methods.select { |x| x =~/new/ }
=> ["new"]
Así que lo que haremos es abrir la clase Class y reescribir new. Repetimos el truco usado en system en la sección 15.5.3. La técnica no es completa, debido a que ciertos objetos preconstruidos como pueda ser el caso de las String se construyen sin que se produzca una llamada a new.

~/rubytesting/programmingRuby/src_of_programming_ruby_by_dave_thomas$ ruby -rdebug ex0681.rb 
Debug.rb
Emacs support available.

ex0681.rb:2:  class Object
(rdb:1) l 1,50
[1, 50] in ex0681.rb
    1  
=>  2    class Object
    3      attr_accessor :timestamp
    4    end
    5    class Class
    6      alias_method :old_new,  :new
    7      def new(*args)
    8        result = old_new(*args)
    9        result.timestamp = Time.now
   10        result
   11      end
   12    end
   13    class Test
   14    end
   15    
   16    obj1 = Test.new
   17    sleep(0.002)  #!sh!
   18    obj2 = Test.new
   19  
   20    obj1.timestamp.to_f
   21    obj2.timestamp.to_f
(rdb:1) b 18
Set breakpoint 1 at ex0681.rb:18
(rdb:1) c
Breakpoint 1, toplevel at ex0681.rb:18
ex0681.rb:18:  obj2 = Test.new
(rdb:1) p obj1
#<Test:0x100361c70 @timestamp=Sun Nov 20 11:54:46 +0000 2011>
(rdb:1) l
[13, 22] in ex0681.rb
   13    class Test
   14    end
   15    
   16    obj1 = Test.new
   17    sleep(0.002)  #!sh!
=> 18    obj2 = Test.new
   19  
   20    obj1.timestamp.to_f
   21    obj2.timestamp.to_f
(rdb:1) n
ex0681.rb:20:  obj1.timestamp.to_f
(rdb:1) obj2
#<Test:0x10035f628 @timestamp=Sun Nov 20 11:55:15 +0000 2011>
(rdb:1) p obj1.timestamp.to_f
1321790086.82083
(rdb:1) p obj2.timestamp.to_f
1321790115.59523
(rdb:1)

Casiano Rodriguez León 2015-01-07