Нет, такого знания нет, но хорошо, что вы можете сделать это самостоятельно . Вот возможная реализация:
Не супер чистый, но работает:
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
Выход:
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
Так что это, очевидно, не так чисто, как крючок, но я думаю, что в конце мы получим довольно хороший результат.
Если бы мы попытались сделать то же самое с: унаследованным, к сожалению, невозможно, потому что: унаследованный вызывается еще до того, как исполнитель выполнения в теле класса:
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
Выход:
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