Is there a hook similar to Class#inherited that's triggered only after a Ruby class definition?
I am late, but I think I have an answer (to anyone who visit here).
You can trace until you find the end of the class definition. I did it in a method which I called after_inherited
:
class Class def after_inherited child = nil, &blk line_class = nil set_trace_func(lambda do |event, file, line, id, binding, classname| unless line_class # save the line of the inherited class entry line_class = line if event == 'class' else # check the end of inherited class if line == line_class && event == 'end' # if so, turn off the trace and call the block set_trace_func nil blk.call child end end end) endend# testing...class A def self.inherited(child) after_inherited do puts "XXX" end endendclass B < A puts "YYY" # .... code here can include class << self, etc.end
Output:
YYYXXX
You may be out of luck. But that's only a warning, not a definitive answer.
Ruby hooks the beginning of the class definition, rather than the end, for Class#inherited
b/c ruby class definitions don't have a real end. They canbe reopened any time.
There was some talk a couple years ago about adding a const_added trigger, but it hasn't gone through yet. From Matz:
I'm not going to implement every possible hook. So when somebody comes with more concrete usage, I will consider this again. It would be
const_added
, notclass_added
.
So this might handle your case - but I'm not sure (it may trigger on the start too, when it's eventually implemented).
What are you trying to do with this trigger? There may be another way to do it.
Use TracePoint
to track when your class sends up an :end
event.
This module will let you create a self.finalize
callback in any class.
module Finalize def self.extended(obj) TracePoint.trace(:end) do |t| if obj == t.self obj.finalize t.disable end end endend
Now you can extend your class and define self.finalize
, which will run as soon as the class definition ends:
class Foo puts "Top of class" extend Finalize def self.finalize puts "Finalizing #{self}" end puts "Bottom of class"endputs "Outside class"# output:# Top of class# Bottom of class# Finalizing Foo# Outside class