After watching episode 6 “Some Hook Methods” of the Pragmatic Screencasts of The Ruby Object Model and Metaprogramming with Dave Thomas I wrote some methods for Class.
class Class
def inherited(subklass)
puts "class #{subklass.inspect} desends from #{self.inspect}"
end
original_new = instance_method(:new)
define_method(:new) do |*args|
puts "#{self}.new called"
original_new.bind(self).call(*args)
end
class << self
original_new = instance_method(:new)
define_method(:new) do |*args|
puts "#{self}.new called with #{args.inspect}"
original_new.bind(self).call(*args)
end
end
end
What happens in IRB?
~ irb -r class.rb
IRB::Irb.new called
IRB::Context.new called
IRB::WorkSpace.new called
IRB::ReadlineInputMethod.new called
IRB::StdioOutputMethod.new called
RubyLex.new called
IRB::SLex.new called
IRB::SLex::Node.new called
IRB::SLex::Node.new called
IRB::SLex::Node.new called
# ... 72 lines of "IRB::SLex::Node.new called"
IRB::SLex::Node.new called
IRB::SLex::Node.new called
IRB::SLex::Node.new called
>>
That’s quite a lot of nodes.
Let’s see what happens when classes are created.
>> class Q;end
RubyToken::TkCLASS.new called
RubyToken::TkSPACE.new called
RubyToken::TkCONSTANT.new called
RubyToken::TkSEMICOLON.new called
RubyToken::TkEND.new called
RubyToken::TkNL.new called
class Q desends from Object
=> nil
>> Class.new(Q)
RubyToken::TkCONSTANT.new called
RubyToken::TkDOT.new called
RubyToken::TkIDENTIFIER.new called
RubyToken::TkLPAREN.new called
RubyToken::TkCONSTANT.new called
RubyToken::TkRPAREN.new called
RubyToken::TkNL.new called
Class.new called with [Q]
Class.new called
class #<Class:0x53c654> desends from Q
=> #<Class:0x53c654>
The new method is not used to create every object.
>> [nil]
RubyToken::TkLBRACK.new called
RubyToken::TkNIL.new called
RubyToken::TkRBRACK.new called
RubyToken::TkNL.new called
=> [nil]
>> Array(1)
RubyToken::TkCONSTANT.new called
RubyToken::TkLPAREN.new called
RubyToken::TkINTEGER.new called
RubyToken::TkRPAREN.new called
RubyToken::TkNL.new called
=> [1]
>> Array.new(1)
RubyToken::TkCONSTANT.new called
RubyToken::TkDOT.new called
RubyToken::TkIDENTIFIER.new called
RubyToken::TkLPAREN.new called
RubyToken::TkINTEGER.new called
RubyToken::TkRPAREN.new called
RubyToken::TkNL.new called
Array.new called
=> [nil]
This has been an exercise into hooks and to see what classes are created.
Leave a Reply