Misc #21143
openSpeficy order of execution const_added vs inherited
Description
The hooks const_added
and inherited
may need to be executed "together".
For example, consider:
module M
def self.const_added(cname) = ...
class C
def self.inherited(subclass) = ...
end
class D < C; end
end
When D
is defined, two hooks are set to run, but in which order?
Both orders make sense in a way:
-
When
inherited
is called, you can observe that the subclass has a permanent name, ergo it was assigned to a constant, which must me stored in a class or module object. Therefore, the constant was added to said class/module beforeinherited
was invoked. -
When
const_added
is called, you canconst_get
the symbol and observe the object is a class, hence with a superclass, hence inheritance already happened.
The patch in ruby#12759 documents and adds a test for (1). Rationale:
-
I believe it would be nice to specify this order.
-
Chose (1) because it is how it works today.
While the motivation for the patch was formal (to remove an ambiguity), after reflecting about this I realized users of Zeitwerk may depend on this. Nowadays, Zeitwerk uses const_added
to set autoloads for child constants in namespaces. Thanks to the current order, code can be used in inherited
hooks normally (it would not be ready if the order was different).