Issue #19742 has been updated by ioquatix (Samuel Williams).
We can consider introducing the PR unchanged, it depends on `permanent_classpath` which is
an internal implementation detail. If we fix `const_set` and `remove_const` to deal with
changing class names, `anonymous?` will reflect that change, since itself it is not making
any determination and rather just returning the existing state that Ruby knows about.
```c
VALUE
rb_mod_anonymous_p(VALUE mod)
{
return RBOOL(!RCLASS_EXT(mod)->permanent_classpath);
}
```
I also think we should consider `Module#permanent?` as described above - that the current
name reflects the valid constant path for `self`. However, I agree, re-assignment can
cause significant confusion. I am okay with the first assignment being considered special.
Certainly that's the case today. After the first assignment, a module is considered
permanent. If that binding is removed, e.g. `remove_const`, we could mark that as such.
Rebinding a constant to a new constant path could reset the permanent name. However, I
feel like that should be solved outside the scope of this PR.
So, in order to keep things focused, are there any changes we'd want to make to the
above implementation?
Alternatively, we could consider:
```c
VALUE
rb_mod_permanent_p(VALUE mod)
{
return RBOOL(RCLASS_EXT(mod)->permanent_classpath);
}
```
However, I believe we'd want to follow up with another PR to correctly manipulate
`permanent_classpath` to make more sense on `remove_const` et al.
----------------------------------------
Feature #19742: Introduce `Module#anonymous?`
https://bugs.ruby-lang.org/issues/19742#change-104403
* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
As a follow-on <from
https://bugs.ruby-lang.org/issues/19521>gt;, I'd like propose
we introduce `Module#anonymous?`.
In some situations, like logging/formatting, serialisation/deserialization, debugging or
meta-programming, we might like to know if a class is a proper constant or not.
However, this brings about some other issues which might need to be discussed.
After assigning a constant, then removing it, the internal state of Ruby still believes
that the class name is permanent, even thought it's no longer true.
e.g.
```
m = Module.new
m.anonymous? # true
M = m
m.anonyomous # false
Object.send(:remove_const, :M)
M # uninitialized constant M (NameError)
m.anonymous? # false
```
Because RCLASS data structure is not updated after the constant is removed, internally the
state still has a "permanent class name".
I want to use this proposal to discuss this issue and whether there is anything we should
do about such behaviour (or even if it's desirable).
Proposed PR:
https://github.com/ruby/ruby/pull/7966
cc @fxn
--
https://bugs.ruby-lang.org/