From: "fxn (Xavier Noria) via ruby-core" Date: 2025-03-13T07:38:13+00:00 Subject: [ruby-core:121323] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited Issue #21143 has been updated by fxn (Xavier Noria). In theory, there could be an incompatibility in projects using Zeitwerk. Let's imagine you have a class `C` defined in `c.rb` and `C::X` defined in `c/x.rb`. If the parent class of `C` has an `inherited` hook, today that hook can refer to `C::X`. The reason for that is that when `C` gets created, `const_added` is invoked and the loader is on time to define an `autoload` for `:X` in `C`. That is how you are able to refer to any constant path in your project any time. (Time ago, this was done with a trace point for the `:class` event.) If we change the order, when the `inherited` hook is invoked `C::X` will raise `NameError`. However, let me also say that I don't know if this usage is present out there. Referring to nested constants in your just created subclass seems a rare use case that in pure Ruby may not even be possible. I'd be ���� to go with @eregon's suggestion because it is simpler and uniform. ---------------------------------------- Misc #21143: Speficy order of execution const_added vs inherited https://bugs.ruby-lang.org/issues/21143#change-112288 * Author: fxn (Xavier Noria) * Status: Feedback ---------------------------------------- The hooks `const_added` and `inherited` may need to be executed "together". For example, consider: ```ruby 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: 1. 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 before `inherited` was invoked. 1. When `const_added` is called, you can `const_get` the symbol and observe the object is a class, hence with a superclass, hence inheritance already happened. The patch in [ruby#12759](https://github.com/ruby/ruby/pull/12759) documents and adds a test for (1). Rationale: 1. I believe it would be nice to specify this order. 1. 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). -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/