No, there no such a hook to my knowledge, but the good thing is you can kind of do it yourself. Here is a possible implementation:
Is not super clean, but it works:
puts RUBY_VERSION # 2.4.1
class Father
def self.engage_super_setup(sub)
puts "self:#{self} sub:#{sub}"
sub.class_eval do
puts "toy:#{@toy}"
end
end
def self.super_setup
if self.superclass.singleton_methods.include?(:engage_super_setup)
superclass.engage_super_setup(self)
end
end
end
Son = Class.new(Father) do
@toy = 'ball'
end.tap { |new_class| new_class.super_setup } # this is needed to:
# 1. call the super_setup method in the new class.
# 2. we use tap to return the new Class, so this class is assigned to the Son constant.
puts Son.name # Son
Output:
self:Father sub:#<Class:0x0055d5ab44c038> #here the subclass is still anonymous since it was not yet assigned to the constant "Son"
toy:ball # here we can see we have acess to the @toy instance variable in Son but from the :engage_super_setup in the Father class
Son # the of the class has been assigned after the constant, since ruby does this automatically when a class is assigned to a constant
So this is obviously not as clean as a hook, but I think at the end we have a pretty good result.
If we had tried to do the same with :inherited sadly is not possible, because :inherited is called even before the execution entoer in the body of the class:
puts RUBY_VERSION # 2.4.1
class Father
def self.inherited(sub)
puts "self:#{self} sub:#{sub}"
sub.class_eval do
puts "toy:#{@toy.inspect}"
end
end
end
class Son < Father
puts "we are in the body of Son"
@toy = 'ball'
end
puts Son.name # Son
Output:
self:Father sub:Son # as you can see here the hook is executed before the body of the declaration Son class runs
toy:nil # we dont have access yet to the instance variables
we are in the body of Son # the body of the class declaration begins to run after the :inherited hook.
Son
TracePoint
. See my answer below, or my answer to this similar question: #32234360 – Potentate