* [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
@ 2025-02-17 7:06 fxn (Xavier Noria) via ruby-core
2025-02-17 7:13 ` [ruby-core:121078] " fxn (Xavier Noria) via ruby-core
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: fxn (Xavier Noria) via ruby-core @ 2025-02-17 7:06 UTC (permalink / raw)
To: ruby-core; +Cc: fxn (Xavier Noria)
Issue #21143 has been reported by fxn (Xavier Noria).
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143
* Author: fxn (Xavier Noria)
* Status: Open
----------------------------------------
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
```
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 module. Therefore, the constant was added to said module 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 https://github.com/ruby/ruby/pull/12759 documents and adds a test for (1). Rationale:
1. I believe it would be nice 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. 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121078] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
@ 2025-02-17 7:13 ` fxn (Xavier Noria) via ruby-core
2025-02-17 12:13 ` [ruby-core:121079] " Eregon (Benoit Daloze) via ruby-core
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: fxn (Xavier Noria) via ruby-core @ 2025-02-17 7:13 UTC (permalink / raw)
To: ruby-core; +Cc: fxn (Xavier Noria)
Issue #21143 has been updated by fxn (Xavier Noria).
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 module 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 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).
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-111994
* Author: fxn (Xavier Noria)
* Status: Open
----------------------------------------
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
```
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 module. Therefore, the constant was added to said module 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 https://github.com/ruby/ruby/pull/12759 documents and adds a test for (1). Rationale:
1. I believe it would be nice 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. 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121079] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
2025-02-17 7:13 ` [ruby-core:121078] " fxn (Xavier Noria) via ruby-core
@ 2025-02-17 12:13 ` Eregon (Benoit Daloze) via ruby-core
2025-02-17 12:18 ` [ruby-core:121080] " Eregon (Benoit Daloze) via ruby-core
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Eregon (Benoit Daloze) via ruby-core @ 2025-02-17 12:13 UTC (permalink / raw)
To: ruby-core; +Cc: Eregon (Benoit Daloze)
Issue #21143 has been updated by Eregon (Benoit Daloze).
For classes/modules not using the `class/module` keyword (e.g. `C = Class.new(parent)`), `inherited` must run first since the inheritance happens before the possible later assignment.
So maybe for consistency `inherited` should run first?
I'm unsure consistency matters too much here.
I checked and TruffleRuby currently behaves like CRuby, i.e. `const_added` before `inherited` for `class`/`module` cases.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-111997
* Author: fxn (Xavier Noria)
* Status: Open
----------------------------------------
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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121080] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
2025-02-17 7:13 ` [ruby-core:121078] " fxn (Xavier Noria) via ruby-core
2025-02-17 12:13 ` [ruby-core:121079] " Eregon (Benoit Daloze) via ruby-core
@ 2025-02-17 12:18 ` Eregon (Benoit Daloze) via ruby-core
2025-02-17 12:42 ` [ruby-core:121082] " fxn (Xavier Noria) via ruby-core
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Eregon (Benoit Daloze) via ruby-core @ 2025-02-17 12:18 UTC (permalink / raw)
To: ruby-core; +Cc: Eregon (Benoit Daloze)
Issue #21143 has been updated by Eregon (Benoit Daloze).
FWIW looking at this stuff I noticed `rb_class_new()` doesn't call `inherited` at all, but `rb_define_class*()` do.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-111998
* Author: fxn (Xavier Noria)
* Status: Open
----------------------------------------
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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121082] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (2 preceding siblings ...)
2025-02-17 12:18 ` [ruby-core:121080] " Eregon (Benoit Daloze) via ruby-core
@ 2025-02-17 12:42 ` fxn (Xavier Noria) via ruby-core
2025-03-13 6:37 ` [ruby-core:121320] " matz (Yukihiro Matsumoto) via ruby-core
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: fxn (Xavier Noria) via ruby-core @ 2025-02-17 12:42 UTC (permalink / raw)
To: ruby-core; +Cc: fxn (Xavier Noria)
Issue #21143 has been updated by fxn (Xavier Noria).
> For classes/modules not using the class/module keyword (e.g. C = Class.new(parent)), inherited must run first since the inheritance happens before the possible later assignment.
Yes, that is why the proposed docs specifically mention the `class` keyword, because it is there where the ambiguity lies.
If you do two things in series, it is to be expected that their side-effects happen in series. Although when that is done in one line, the programmer needs to understand that the expression is evaluated first, and then the result assigned to the constant.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112000
* Author: fxn (Xavier Noria)
* Status: Open
----------------------------------------
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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121320] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (3 preceding siblings ...)
2025-02-17 12:42 ` [ruby-core:121082] " fxn (Xavier Noria) via ruby-core
@ 2025-03-13 6:37 ` matz (Yukihiro Matsumoto) via ruby-core
2025-03-13 7:38 ` [ruby-core:121323] " fxn (Xavier Noria) via ruby-core
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: matz (Yukihiro Matsumoto) via ruby-core @ 2025-03-13 6:37 UTC (permalink / raw)
To: ruby-core; +Cc: matz (Yukihiro Matsumoto)
Issue #21143 has been updated by matz (Yukihiro Matsumoto).
Status changed from Open to Feedback
I think @eregon's opinion here is reasonable. But I don't want to break any existing code. I'd like to experiment `inherited`-then-`const_added` order works (or not).
If it works, I'd like to change the order. If it doesn't I'like to keep the current order (and document somewhere).
Matz.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112285
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121323] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (4 preceding siblings ...)
2025-03-13 6:37 ` [ruby-core:121320] " matz (Yukihiro Matsumoto) via ruby-core
@ 2025-03-13 7:38 ` fxn (Xavier Noria) via ruby-core
2025-03-13 11:41 ` [ruby-core:121331] " byroot (Jean Boussier) via ruby-core
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: fxn (Xavier Noria) via ruby-core @ 2025-03-13 7:38 UTC (permalink / raw)
To: ruby-core; +Cc: fxn (Xavier Noria)
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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121331] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (5 preceding siblings ...)
2025-03-13 7:38 ` [ruby-core:121323] " fxn (Xavier Noria) via ruby-core
@ 2025-03-13 11:41 ` byroot (Jean Boussier) via ruby-core
2025-03-13 12:31 ` [ruby-core:121339] " byroot (Jean Boussier) via ruby-core
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-03-13 11:41 UTC (permalink / raw)
To: ruby-core; +Cc: byroot (Jean Boussier)
Issue #21143 has been updated by byroot (Jean Boussier).
Calling `inherited` before `const_added` is doable and I doubt it would cause much backward compatibility issues except for one thing: the class being anonymous when `inherited` is called.
There are a number of `inherited` methods in Rails that do expect the class to have a name (it handles anonymous classes in a degraded way). Just to give one example: https://github.com/rails/rails/blob/3626b8f52c425c2dd7a0d0aa698cff9f10d789b3/actionpack/lib/action_controller/railties/helpers.rb#L12
Here `module_parents` rely on `Module#name`.
But if we still assign the `name` before calling `inherited`, then I think we can change the order without problem.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112301
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121339] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (6 preceding siblings ...)
2025-03-13 11:41 ` [ruby-core:121331] " byroot (Jean Boussier) via ruby-core
@ 2025-03-13 12:31 ` byroot (Jean Boussier) via ruby-core
2025-03-13 13:16 ` [ruby-core:121341] " fxn (Xavier Noria) via ruby-core
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-03-13 12:31 UTC (permalink / raw)
To: ruby-core; +Cc: byroot (Jean Boussier)
Issue #21143 has been updated by byroot (Jean Boussier).
Here's a tentative implementation, with some ruby specs added: https://github.com/ruby/ruby/pull/12927
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112309
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121341] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (7 preceding siblings ...)
2025-03-13 12:31 ` [ruby-core:121339] " byroot (Jean Boussier) via ruby-core
@ 2025-03-13 13:16 ` fxn (Xavier Noria) via ruby-core
2025-03-13 13:51 ` [ruby-core:121344] " byroot (Jean Boussier) via ruby-core
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: fxn (Xavier Noria) via ruby-core @ 2025-03-13 13:16 UTC (permalink / raw)
To: ruby-core; +Cc: fxn (Xavier Noria)
Issue #21143 has been updated by fxn (Xavier Noria).
> But if we still assign the name before calling inherited, then I think we can change the order without problem.
Just to clarify in the thread, it is more than the name. Nowadays, the constant exists in `inherited` (maybe your patch preserves this too?)
Provided both *internal* inheritance and constant assignment have happened, we are discussing the order in which the user-facing callbacks are invoked.
As the description says, in `const_added`, today inheritance already happened (the value has a superclass), but note that the `inherited` callback was not fired. This is not inconsistent if we consider internal operations to be decouple from the public hooks. On the other hand, in `inherited`, the constant was already assigned (`const_get` gives it to you and the subclass has a permanent name).
I am fine either way, though reordering would make me document in Zeitwerk that you cannot refer to certain constants in `inherited` hooks. Sometimes, the need to write such docs is a signal that the feature is not quite right.
So, fine either way, but slightly slanted towards keeping things as they are and applying my doc + specs patch :).
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112312
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121344] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (8 preceding siblings ...)
2025-03-13 13:16 ` [ruby-core:121341] " fxn (Xavier Noria) via ruby-core
@ 2025-03-13 13:51 ` byroot (Jean Boussier) via ruby-core
2025-03-13 14:00 ` [ruby-core:121345] " Eregon (Benoit Daloze) via ruby-core
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-03-13 13:51 UTC (permalink / raw)
To: ruby-core; +Cc: byroot (Jean Boussier)
Issue #21143 has been updated by byroot (Jean Boussier).
> Nowadays, the constant exists in inherited (maybe your patch preserves this too?)
Right. That is something that can also have an impact. Right now my patch doesn't preserve this, but it would be possible to do it.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112316
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121345] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (9 preceding siblings ...)
2025-03-13 13:51 ` [ruby-core:121344] " byroot (Jean Boussier) via ruby-core
@ 2025-03-13 14:00 ` Eregon (Benoit Daloze) via ruby-core
2025-03-13 14:03 ` [ruby-core:121346] " byroot (Jean Boussier) via ruby-core
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Eregon (Benoit Daloze) via ruby-core @ 2025-03-13 14:00 UTC (permalink / raw)
To: ruby-core; +Cc: Eregon (Benoit Daloze)
Issue #21143 has been updated by Eregon (Benoit Daloze).
@byroot 's PR swaps `rb_class_inherited()` and `rb_const_set()`, so AFAIK the constant is not set yet in the "lexical parent/namespace" module when `inherited` is called.
It's kind of nice to keep "actual constant assignment" and "calling const_added" together, and also it's consistent with `C = Class.new(parent)` where it happens in the same order as in that PR.
I'm just not sure if it might cause compatibility issues, but I suggest to try, we are early in the dev cycle and can always revert if it causes problems.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112317
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121346] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (10 preceding siblings ...)
2025-03-13 14:00 ` [ruby-core:121345] " Eregon (Benoit Daloze) via ruby-core
@ 2025-03-13 14:03 ` byroot (Jean Boussier) via ruby-core
2025-03-13 15:40 ` [ruby-core:121351] " fxn (Xavier Noria) via ruby-core
2025-03-14 3:47 ` [ruby-core:121358] [Ruby " nobu (Nobuyoshi Nakada) via ruby-core
13 siblings, 0 replies; 15+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-03-13 14:03 UTC (permalink / raw)
To: ruby-core; +Cc: byroot (Jean Boussier)
Issue #21143 has been updated by byroot (Jean Boussier).
> I'm just not sure if it might cause compatibility issues, but I suggest to try, we are early in the dev cycle and can always revert if it causes problems.
I feat it might cause issues, as mentioned by @fxn but yes we can try. I should add a spec for that too though.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112318
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121351] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (11 preceding siblings ...)
2025-03-13 14:03 ` [ruby-core:121346] " byroot (Jean Boussier) via ruby-core
@ 2025-03-13 15:40 ` fxn (Xavier Noria) via ruby-core
2025-03-14 3:47 ` [ruby-core:121358] [Ruby " nobu (Nobuyoshi Nakada) via ruby-core
13 siblings, 0 replies; 15+ messages in thread
From: fxn (Xavier Noria) via ruby-core @ 2025-03-13 15:40 UTC (permalink / raw)
To: ruby-core; +Cc: fxn (Xavier Noria)
Issue #21143 has been updated by fxn (Xavier Noria).
The problem with `C = Class.new(parent)` is that it is a totally different mindset.
In the thing we are discussing, the interpreter is in charge.
In the other example, the user has decided to decouple both things. That anonymous class could be stored in a variable, passed three frames up and down, and perhaps be assigned to a constant 10 minutes later. Or never.
That is, in my mind instantiating an anonymous class object totally decouples the callbacks in a way that is expected.
Furthermore, if you have an autoload for `:C`:
```ruby
autoload :C, 'x'
```
`const_added` is going to be called before `inherited` anyway (because it is triggered by the `autoload` call itself). Analogous situation in my view, the user decided to decouple the actions.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112323
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [ruby-core:121358] [Ruby Misc#21143] Speficy order of execution const_added vs inherited
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
` (12 preceding siblings ...)
2025-03-13 15:40 ` [ruby-core:121351] " fxn (Xavier Noria) via ruby-core
@ 2025-03-14 3:47 ` nobu (Nobuyoshi Nakada) via ruby-core
13 siblings, 0 replies; 15+ messages in thread
From: nobu (Nobuyoshi Nakada) via ruby-core @ 2025-03-14 3:47 UTC (permalink / raw)
To: ruby-core; +Cc: nobu (Nobuyoshi Nakada)
Issue #21143 has been updated by nobu (Nobuyoshi Nakada).
byroot (Jean Boussier) wrote in #note-9:
> Here's a tentative implementation, with some ruby specs added: https://github.com/ruby/ruby/pull/12927
`vm_declare_class` calls `rb_class_inherited` too.
----------------------------------------
Misc #21143: Speficy order of execution const_added vs inherited
https://bugs.ruby-lang.org/issues/21143#change-112329
* 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/
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-03-14 3:47 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-17 7:06 [ruby-core:121077] [Ruby master Misc#21143] Speficy order of execution const_added vs inherited fxn (Xavier Noria) via ruby-core
2025-02-17 7:13 ` [ruby-core:121078] " fxn (Xavier Noria) via ruby-core
2025-02-17 12:13 ` [ruby-core:121079] " Eregon (Benoit Daloze) via ruby-core
2025-02-17 12:18 ` [ruby-core:121080] " Eregon (Benoit Daloze) via ruby-core
2025-02-17 12:42 ` [ruby-core:121082] " fxn (Xavier Noria) via ruby-core
2025-03-13 6:37 ` [ruby-core:121320] " matz (Yukihiro Matsumoto) via ruby-core
2025-03-13 7:38 ` [ruby-core:121323] " fxn (Xavier Noria) via ruby-core
2025-03-13 11:41 ` [ruby-core:121331] " byroot (Jean Boussier) via ruby-core
2025-03-13 12:31 ` [ruby-core:121339] " byroot (Jean Boussier) via ruby-core
2025-03-13 13:16 ` [ruby-core:121341] " fxn (Xavier Noria) via ruby-core
2025-03-13 13:51 ` [ruby-core:121344] " byroot (Jean Boussier) via ruby-core
2025-03-13 14:00 ` [ruby-core:121345] " Eregon (Benoit Daloze) via ruby-core
2025-03-13 14:03 ` [ruby-core:121346] " byroot (Jean Boussier) via ruby-core
2025-03-13 15:40 ` [ruby-core:121351] " fxn (Xavier Noria) via ruby-core
2025-03-14 3:47 ` [ruby-core:121358] [Ruby " nobu (Nobuyoshi Nakada) via ruby-core
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).