[ruby-core:113966] [Ruby master Bug#19742] Introduce `Module#anonymous?`

Issue #19742 has been reported by ioquatix (Samuel Williams). ---------------------------------------- Bug #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). ❤️ for `anonymous?`. Regarding the broader topic, the fundamental thing to discuss is whether permanent class names and constants should have any more coupling after initial constant assignment (when the name becomes permanent). Because, today, as you know, they don't. That is, once a first constant assignment is done, class and module objects are like any other Ruby object, where `name` is just an attribute. You can do with them object whatever you want, store them wherever you want, that storage can be reassigned, etc. They are no different than `Object.new`. By the same argument, class and module objects do not belong to a namespace. Constants do, different. For example, in ancestor chains you store module objects. They are objects, whether they are reachable via a constant at any point in time is irrelevant. If you remove the original constant, the object is still there. Because storage and objects are orthogonal concepts in Ruby. Another example ``` klass = User user = User.new User = 1 user.class.equal?(klass) # => true user.class.name # => 'User' ``` So... coupling the name to storage would be an important change. However, if coupled to the original constant removal, it would be symmetrical, it could make sense (assuming any change in the original constant path triggers the logic). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103624 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). There is another formulation of the opposite of "anonymous" which could be the following: ```ruby class Module def permanent? Object.const_get(self.name).equal?(self) end end ``` This would be true if the object is reachable by the name it says it is. It's a little slower, but perhaps a better approach. We might be able to optimise it internally if the object/module know's it's parent namespace and name within that namespace (i.e. don't need to use `const_get`). So it might be true that `anonymous?` and `permanent?` are related but different. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103625 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by janosch-x (Janosch Müller). `#permanent?` is not very descriptive IMO. If I hadn't seen the code above, or the C code with that vocabulary, I would have a hard time guessing what its about. I'd probably guess it has to do with GC or so. As seen in Xavier Noria's example, the word `anonymous` also does not cover *all* the ways in which a `Module#name` can become useless or wrong. Then again, it might be really rare that people need to differentiate between the const-override case and say, classical anonymous modules or removed consts. So maybe it is not worth it to leak these subtleties to end users and the slightly imprecise `anonymous` is fine. A short and precise name that covers all cases is hard to find. Something like `#assigned_to_original_const?` doesn't exactly roll off the tongue... ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103636 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). Permanent is already a word used in the Ruby documentation and implementation. I agree it might not be clear, but it's already established when talking about "class paths" and names. if we introduce a new name, we should have a strong reason to do so. Out of the two, I'd say `permanent?` as proposed has a stronger meaning than `anonymous?` as in some cases both can be false but in that case, `permanent?` is correct while `anonymous?` is probably at best misleading and at worst wrong. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103637 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Let me clarify the vocabulary as I see it: And _anonymous_ module has `nil` as name: `anonymous?` A module may have a _temporary_ name if it was never assigned to a constant that belongs to a module with a permanent name. A module may have a _permanent_ name if it was at some point assigned to a constant in a module with a permanent name. Please excuse the circularity, but we all know what that means. It is three concepts. Note that permanent has nothing to do with the name being a working constant path. Permanent means what it means: there is no way the name is going to change (using public API). In that sense, I believe the proposal is not aligned with the current way things work. Note also that "temporary" and "permanent" are qualities of the name, not the module. My personal point of view is that any attempt to introduce "parent" concepts, or steering into coupling names and constant paths is going to leak. Because in Ruby objects and storage are decoupled. People used to have types in their language may have expectations or misconceptions, but those should be revised, Ruby does not have syntax for types. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103638 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). The concepts are discussed in the code, but they shouldn't be assumed as canonical, IMHO. ```c /** * Returns +classpath+ of _klass_, if it is named, or +nil+ for * anonymous +class+/+module+. A named +classpath+ may contain * an anonymous component, but the last component is guaranteed * to not be anonymous. <code>*permanent</code> is set to 1 * if +classpath+ has no anonymous components. There is no builtin * Ruby level APIs that can change a permanent +classpath+. */ static VALUE classname(VALUE klass, bool *permanent) ``` A class/module that is assigned a name via `set_temporary_name` may still be anonymous, so I believe the above comment needs to be updated. In the code, when something is not `permanent`, a `temporary` class path may be generated: ```c static VALUE make_temporary_path(VALUE obj, VALUE klass) { VALUE path; switch (klass) { case Qnil: path = rb_sprintf("#<Class:%p>", (void*)obj); break; case Qfalse: path = rb_sprintf("#<Module:%p>", (void*)obj); break; default: path = rb_sprintf("#<%"PRIsVALUE":%p>", klass, (void*)obj); break; } OBJ_FREEZE(path); return path; } ``` To clarify, the documentation states that when `mod.name == nil`, the `mod` is anonymous. But it does not state that when `mod.name =! nil`, the module is permanent AFAICT. In any case, we should probably clarify this in the documentation. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103639 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). I thought "permanent" was mostly internal jargon, where is in the documentation mentioned? In the public API you have that a `nil` name means the module is anonymous. If the name is not `nil`, the module is not anonymous (and that, by definition, includes temporary names). I believe that is all user-facing? ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103640 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). Just because `name == nil` implies it's anonymous, does not mean that anonymous implies that `name == nil`. In fact, we don't have any `anonymous?` implementation yet to define this behaviour. I don't know if the documentation clarifies this or not, but I don't recall seeing it clearly outlined anywhere. If anything, I think this issue is a good place to figure out what we want, and then add clear and canonical documentation (as well as specs). Until my previous PR `set_temporary_name`, which includes a discussion of `permanent`, I don't think there was any user facing documentation, but the implementation is clear on the behaviour. I'd be okay with changing this documentation if we want to clarify some aspects of it (we still have until Ruby 3.3 release which is months away). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103641 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). I'll add my observation that Marshal states it cannot handle anonymous modules, but I say, it cannot handle ANY non-permanent (temporary) modules (assuming `permanent?` as defined above). The difference is subtle but demonstrated by this example: ```ruby # (1) Expected: point = Struct.new(:x, :y) Marshal.dump(point.new(1, 2)) # can't dump anonymous class #<Class:0x00000001084f14c0> (TypeError) # (2) Point2 is not anonymous (it did have a name), but it's also not permanent (the name is no longer valid). Point = Struct.new(:x, :y) point = Point Point2 = Point Object.send(:remove_const, :Point) Marshal.dump(Point2.new(1, 2)) # undefined class/module Point (ArgumentError) # (3) Try to trick Marshal: Point = Struct.new(:x, :y) Marshal.dump(point.new(1, 2)) # Point can't be referred to (TypeError) ``` In all the above examples, the marshalled class may or may not be anonymous, but it's always not permanent, according to my (slightly fixed) definition: ```ruby class Module def permanent? Object.const_get(self.name).equal?(self) rescue nil end end ``` If being "not anonymous" was the only criteria, re-assigning the constants would ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103642 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). The documentation for `Module#name` says:
Returns the name of the module mod. Returns nil for anonymous modules.
So, _if_ the module is anonymous, _then_ the name is `nil`. Logically, that does not rule out as a possibility that a non-anonymous module may also have a `nil` name, but I believe you take that for granted. If you are not anonymous, you have a name (ie, a value that is not `nil`), that is the common meaning of something not being anonymous. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103643 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Let me add for context that Active Support has had `Module#anonymous?` for many years, I wrote it myself ([commit](https://github.com/rails/rails/commit/b8bb54af7ff6652327d99f6a7cf5c96a3f3f87...)) when the anonymous modules had an empty string as name. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103644 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). Anyone can do the following: ```ruby my_module = Module.new do def self.name "Hello World" end end ``` Is that module anonymous or not? ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103645 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Agree, but that method is not `Module#name`. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103646 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). I don't understand, is this correct or not? ```ruby class Module def anonymous? name == '' || name.nil? end end Module.new.anonymous? # => true my_module = Module.new do def self.name "Hello World" end end my_module.anonymous? # => false ``` ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103647 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Oh, I thought you meant that the module has a name and had not been assigned to a constant. If the module has a name, then not being considered to be anonymous is the least surprising definition to me. You could also have ```ruby class C def self.name nil end end ``` However, I think overriding such a core method for an attribute that is out of reach, managed internally by Ruby, is questionable and predicates may be well-defined for the common case, and obviate situations like this. With this definition, can you say an anonymous module was never assigned to a constant? No, no more. However, you can add "without an overwritten name" to make the statement hold. We could say that an empty array has 0 size. Can people override `Array#size` to return 7? Yes, they can. But API docs do not need to cover such possibilities. If you override, you're on your own with the consequences. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103648 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). Should setting a temporary name make a module not anonymous? I found the following use cases in Rails: ```ruby unless controller_class.anonymous? controller_class.name.delete_suffix("Controller").underscore end ``` ```ruby def self.kind @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous? end ``` ```ruby def self.controller_name @controller_name ||= (name.demodulize.delete_suffix("Controller").underscore unless anonymous?) end ``` ```ruby def controller_path @controller_path ||= name.delete_suffix("Controller").underscore unless anonymous? end ``` ```ruby def mailer_name @mailer_name ||= anonymous? ? "anonymous" : name.underscore end ``` So, I think the usage of anonymous is already ossified by Rails, even if I disagree. To me, anonymous means it cannot be named, but there is a difference between "proper noun" and "common noun". If you refer to a "person", the person does not have a proper name, they are anonymous. If you refer to "Samuel", you are referring to a specific person, which is not anonymous. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103650 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Yeah, we do not see it the same way. Anonymous to me means you don't have a name. If the module has a name, done, it is not anonymous. If you have a _temporary_ name, in particular you have a name. To be honest, I would leave modules anonymous until they are assigned to a constant in a non-anonymous module. That is, I'd only have two states, anonymous, and non-anonymous: ```ruby m = Module.new m.name # => nil m::C = Class.new m::C.name # => nil, in my ideal design, not real A::B = m::C m::C.name # => "A::B", this does work this way ``` but this cannot be changed even if we agreed, only sharing for the discussion :). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103651 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). I'm not that different, except Anonymous to me means you don't have a name [that resolves to self]. If the module has a name that resolves to itself, it is not anonymous. I would say a lot of the rails code should be rewritten just to check `name` itself, e.g. ``` @mailer_name ||= anonymous? ? "anonymous" : name.underscore # becomes @mailer_name ||= name&.underscore || "anonymous" @controller_name ||= (name.demodulize.delete_suffix("Controller").underscore unless anonymous?) # becomes @controller_name ||= (name ? name.demodulize.delete_suffix("Controller").underscore : nil) ``` I think this is much more direct and I don't think Rails should monkey patch Module in this way. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103652 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by janosch-x (Janosch Müller). fxn (Xavier Noria) wrote in #note-17:
def self.name [...] I think overriding such a core method for an attribute that is out of reach, managed internally by Ruby, is questionable [...] Can people override `Array#size` to return 7? Yes, they can.
The problem with `name` is that it is a common, uh, name. It is also not as obvious that it is a part of the core as with `Array#size`. Coincidental overrides like [these](https://github.com/search?q=repo%3Afaker-ruby%2Ffaker%20name&type=code) are probably somewhat common. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103653 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). @janosch-x agreed, in Zeitwerk I do my best at [reaching the original `Module#name`](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/real_mod_name.rb) because of that. @ioquatix yeah, I understand your point of view. However, we disagree due to two reasons: The first one is that Ruby docs (today) agree with my definition: If a module is anonymous, then its name is `nil`. If `mod.anonymous?` returned true and `mod.name` was not `nil`, we'd violate existing Ruby semantics. The second one is more conceptual: once a name is set, its relationship with storage in the Ruby model is non-existent. You cannot assume or expect anything, because Ruby semantics decouple names and storage. A name, to me, is a string that was once set according to some rules. From then on, it is a mere string. So, I believe trying to mix "anonymous" in between name and storage does not go in the right direction, `reachable_from_its_name?` would be more aligned (not a proposal, just to illustrate my point). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103654 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams).
The first one is that Ruby docs (today) agree with my definition: If a module is anonymous, then its name is `nil`. If `mod.anonymous?` returned true and `mod.name` was not `nil`, we'd violate existing Ruby semantics.
There is no semantics for `anonymous?` because it does not exist in Ruby yet. The problem is, in your logic, it's "if" not "iff". I think conceptually, a name is set needs to be clarified - do you mean a permanent name or a non-permanent name? I wonder if we should change `name` to return nil if `set_temporary_name` is used to avoid this confusion. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103655 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria).
There is no semantics for anonymous? because it does not exist in Ruby yet.
I used the word "semantics" because the docs use the English word "anonymous", which is not formal, but would be surprising that `anonymous?` does not behave like like what "anonymous" says today.
The problem is, in your logic, it's "if" not "iff".
Yes, but the other direction is "if the name is `nil`, then the module is anonymous". But this is not what we are discussing right? We are discussing if an anonymous module can have a name that is not `nil`. To see that is not possible, you need the arrow in the docs.
I think conceptually, a name is set needs to be clarified - do you mean a permanent name or a non-permanent name? I wonder if we should change name to return nil if set_temporary_name is used to avoid this confusion.
I personally believe it is fine, even expected, that `name` returns the temporary name. Because that is what it does when implicitly set by Ruby today, and because, well, it is the name at this point in time. It may change, variable vs constant. Hey let me say explicitly that I am participating in the discussion to contribute to it, but Ruby core are who define how the language evolves. So, given we come from different angles that won't reconcile, whatever core decides is going to be OK for me :). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103656 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by rubyFeedback (robert heiler).
I don't think Rails should monkey patch Module in this way either.
This may be a problem with some of rails idioms, e. g. how HashWithIndifferentAccess arose, to give one example. While one may understand the use case (not having to care about same-named key strings and key symbols), it can be confusing when the terminology does not match e. g. matz's expectation or terminology. To the actual topic: this is the first time I heard about "permanent?". I think I heard about anonymous modules before, but never ".permanent?()". For the purpose of the proposal it may be easier to ignore .permanent? altogether and just focus on the question of the usefulness / use case of "Module#anonymous?". (I have no particular opinion on whether it is needed or not; in my own code I rarely have unnamed things, not even using Class.new either. I try to keep meta-programming as simple as possible to avoid my poor brain having to figure out what I did months ago with some spaghetti code.) ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103657 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). @ioquatix oh wait, we might have two questions in our minds. I am like: Can a module whose `mod.name` is not `nil` be `anonymous?`. Answer is, if we want to agree with the current docs, it cannot be, because `Module#name` has to return `nil` for anonymous modules. Then, I guess you had in mind the definition of `Module#anonymous?`. That needs an "iff" indeed. However, if you have to define, then making that condition an "iff" could not be controversial, it is the natural extension to me. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103658 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by Eregon (Benoit Daloze).
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).
I think it would be great to reflect it in the Module#name if a Module is no longer reachable through that name. Either setting it back to `nil` or something like `#<no longer reachable, was: Foo::Bar>`. Regarding `Module#anonymous?`, I think it should be true for `Module.new::C = Module.new #=> #<Module:0x00007f92d6c66770>::C` (note, the `.name` of that is `"#<Module:0x00007f92d6c66770>::C"`, it's not nil) I.e., it should only return `false` if `Module#name` is a valid constant path, i.e., if all components of the the constant path are valid constant names. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103659 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by Eregon (Benoit Daloze). Eregon (Benoit Daloze) wrote in #note-27:
Regarding `Module#anonymous?`, I think it should be true for `Module.new::C = Module.new #=> #<Module:0x00007f92d6c66770>::C` (note, the `.name` of that is `"#<Module:0x00007f92d6c66770>::C"`, it's not nil) I.e., it should only return `false` if `Module#name` is a valid constant path, i.e., if all components of the the constant path are valid constant names.
It would mean on `remove_const` and on `const_set(name, v)` when there was already a constant `name`, to change the name of the old constant if it is a module. And also do so recursively for any constant in that module, i.e., mirroring what we do when we name a module, it also names all module constant of that module. Then I think we could finally trust without exception that a non-anonymous `Module#name` is a valid way to reach that Module. That would be great. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103661 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria).
It would mean on remove_const and on const_set(name, v) when there was already a constant name, to change the name of the old constant if it is a module.
If I understand this correctly, I believe it is not possible preserving today's rules. Nowadays, if a module was ever stored in a constant that belonged to a module with a permanent name, it has a permanent name. In other words, today, this cannot happen: ``` A::C.anonymous? # => true, not possible ``` If a reassignment or `remove_const` changed the name of the module to temporary, you could fall into that easily: ``` X::Y = Module.new Z::W = X::Y X::Y = Module.new ``` After that, `Z::W` cannot be anonymous if `Z` has a permanent name. Let me say it again: Ruby is not Java, there are no types or type identifiers or anything. It's all storage and objects. Chasing that a name is a constant path that resolves to the same object is going to leak, or will need to change the language. If a logical system does not have constraints, you won't get properties that do not follow. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-103738 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

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>, 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/

Issue #19742 has been updated by ko1 (Koichi Sasada). Another idea is introducing `#permanent_name` for Ruby 3.2's name which returns nil if it is not named. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106237 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). @ko1 I think that is a good direction, because with the introduction of temporary names as a blessed concept with API and all, I believe there are several matching APIs that may arise. One proposal could be: ``` Module#name -> as it is today Module#temporary_name -> there is a temporary name or nil Module#permanent_name -> there is a permanent name or nil Module#anonymous? -> both temporary and permanent names are nil ``` For example, edges case that test how do we think about this: ``` m = Module.new m.name #=> nil m.temporary_name #=> nil m.permanent_name #=> nil m.anonymous? #=> true m::C = Class.new m::C.name #=> "#<Module:0x0000000102cd4620>::C" m::C.temporary_name #=> "#<Module:0x0000000102cd4620>::C" m::C.permanent_name #=> nil m::C.anonymous? #=> false M = m m::C.name #=> "M::C" m::C.temporary_name #=> nil m::C.permanent_name #=> "M::C" m::C.anonymous? #=> false ``` ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106245 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by Dan0042 (Daniel DeLorme). After reading all the above it doesn't seem like there's a clear agreement on what this proposed `#anonymous?` is supposed to be. If it's just equivalent to `.name.nil?` then what is the point? Else, what is the behavior exactly? ```ruby m::A.name #=> "#<Module:0x00007f27f032d678>::A" m::A.anonymous? #=> true or false? M = m m::A.name #=> "M::A" m::A.anonymous? #=> false Object.send(:remove_const, :M) m::A.name #=> "M::A" m::A.anonymous? #=> true or false? ``` And once the behavior is clarified, what is an example use case? It's very rare to use either an anonymous namespace or remove_const, so what would you use this `#anonymous?` method for? Some things have been mentioned like logging/formatting, serialisation/deserialization, debugging or meta-programming, but concrete examples are missing. Since Ruby 3.0, Module#name can return a string like `"#<Module:0x00007f27f032d678>::A"` whereas previously it returned nil. I can imagine `#anonymous?` could be a way to get back the equivalent of `.name.nil?` in Ruby 2.7. The current implementation in Rails is probably buggy since Ruby 3.0, but no one has ever triggered the bug since no one ever uses anonymous modules. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106259 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by Eregon (Benoit Daloze). Agreed, `anonymous?` seems not well defined for the temporary name case. In fact I would think of `anonymous?` as `!fully_named` and indeed for the anecdote TruffleRuby already has this meaning for anonymous [internally](https://github.com/oracle/truffleruby/blob/1f80340cfdfb46bb987738350d541eaf7...). Adding `Module#permanent_name` seems potentially useful. Maybe `Module#temporary_name` too, although if there is `Module#permanent_name` it's the same as `mod.name unless mod.permanent_name`. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106262 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by Eregon (Benoit Daloze). Ah BTW one line below that link we see something interesting which can be repro'd on CRuby like: ```ruby irb(main):006:0> m = Module.new => #<Module:0x00007fd24624d540> irb(main):007:0> m::C = Class.new => #<Module:0x00007fd24624d540>::C irb(main):008:0> c=m::C.new => #<#<Module:0x00007fd24624d540>::C:0x00007fd246515f20> irb(main):009:0> Marshal.dump c (irb):9:in `dump': can't dump anonymous class #<Module:0x00007fd24624d540>::C (TypeError) ``` So Ruby already calls a module/class with a temporary name as "anonymous" (yet `m::C.name` returns a String). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106263 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). @Dan0042 yes, there are different points of view expressed, and at some point Rails core will take one direction or another. In my personal proposal, none of the objects are `anonymous?`, because, for me, a temporary name is name. And a permanent name is a name too. If you have a name, you are not anonymous. (@ioquatix had a different point of view.) The last of your examples is important. In Ruby "permanent name" and "being reachable through the contant path" are orthogonal concepts. Once the permanent name is set, there is no public API to change it. It is frozen, and what happens to the perhaps dozen places where the object was stored is irrelevant. The point of `anonymous?` is to have a predicate that expresses `name.nil?` with more concision. If you grep the Rails project, you'll see it used in a bunch of places (it is defined by Active Support). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106264 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by Dan0042 (Daniel DeLorme). In Rails this method is used for things like `name.underscore unless anonymous?` so it's pretty clear to me it should return true in case of a temporary name, otherwise `name.underscore` results in garbage like `"#<module:0x00007fe87f033288>/x"` ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106270 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). @Dan0042 right, it could be the case that in Rails anything autoloadable has a permanent name and that has made the predicate sufficient in practice after 3.0. I introduced that predicate myself back in 2010 because you got an empty string in 1.8 and `nil` in 1.9, so `anonymous?` at the same time had meaning and was portable. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106271 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Correction: I have looked at the logs. It was introduced because of conciseness initially (the same way in Ruby we prefer `array.empty?` to `array.length == 0`, you prefer a method that captures the meaning). Right after that, the abstraction was leveraged to make the code portable. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106272 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by jeremyevans0 (Jeremy Evans). I'm against `Module#anonymous?`, because it's ambiguous. I would expect modules with temporary and not permanent names to be anonymous. If you could never refer to module by absolute constant reference, I would expect it to be should be considered anonymous, even if it has a temporary name. However, taken literally, `anonymous` means no name at all, so I can certainly understand arguments that any name should mean `anonymous?` returns false. So `permanent_name` makes more sense to me, as it is less ambiguous. For Rails, `permanent_name&.underscore` seems better than `name.underscore unless anonymous?`. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106273 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). @jeremyevans0 I agree. My defense of `anonymous == name.nil?` is based on the meaning of the adjective, as you said. You are anonymous unless you have a name. The discrepancy in this thread comes from "I have use cases in which I want to know if it does not have a permanent name". Well, fair enough, but that does not mean `anonymous?` is a good name. For example, `permanent_name.nil?` is crystal clear in contrast, and the correspondence would be `permanent_name?` (not proposing, just for the sake of the argument). For example, `marshal.c` now just checks if the name starts with `#`, I suspect this is also out-of-date now. You should check if the permanent name is `nil`. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106274 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by ioquatix (Samuel Williams). I think we can assume this is a fair definition, but I'd like to confirm it with @matz: ```ruby class Module def permanent? if name = self.name Object.const_get(self.name).equal?(self) end rescue NameError false end def anonymous? !permanent? end end ``` However, alternatively, we could defer to whether a class has (or had) a permanent name. The problem is, they are subtly different. The former (example) is quite a robust definition, while the latter (depending on whether a permanent name has or was assigned) is more prone to edge cases (like `const_remove` as discussed). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106276 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by Dan0042 (Daniel DeLorme). @ioquatix I think your definition of "permanent" doesn't quite work, semantically. A name can be said to be permanent if doesn't change (even after remove_const for example). What you have there is the opposite; if a module stops being permanent after remove_const, it can't really be said to have been permanent in the first place. Maybe something like `#namespace?` would be a better name for that, in the sense of "this module can currently be used as a namespace". ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106280 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Same. The name is called "permanent" because it does not change, the predicate above would be `reachable_through_its_name?`. But then, the Ruby language does no have any expectation about the name of classes and modules. If there was some, it would be present and enforced by the language. The name is an attribute of class and module objects, a string, and that is pretty much it. To me, `X = Module.new` and `Y = String.new` are essentially the same. It is true that the first one has a side-effect, but other than that this is storage and objects, and those are orthogonal. You don't even have "namespaces", a module does not have a namespace. A module is an object and can be stored in 7 constants and 4 variables. In Ruby, class and module objects have constants and that is all. It's a pretty weak model in that sense (meaning, you cannot derive much from it). ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106286 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). I have all these matters in my head pretty clearly (and I am writing a book about constants), but in case someone is reading and is not used to the orthogonality of all this, you can even have a permanent set that is not reachable even when created: ```ruby M = Module.new N = M Object.send(:remove_const, :M) N::C = Class.new N::C.name # => "M::C" module N class D end end N::D.name # => "M::D" ``` The reason is that the resolution algorithms determine on which class or module **object** you are creating the constants. The answer is "in the one **stored** in the `N` constant stored in the class object stored in the `Object` constant". OK, you got an object. It has a name attribute, and from that string you derive a new string. It is all quite orthogonal. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106287 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by matz (Yukihiro Matsumoto). First, given the existence of the Module#set_temporary_name method as well, it seems somewhat confusing what the name of this method implies. So, it may be necessary to first clarify what this method really wants to accomplish. In general, in Ruby, the referenced object does not know information about the referencing object (or variables/constants). Class names are an exception, but we recognize that they are for convenience purposes only and are not essential information. The proposed method would have a greater impact than OP thinks, since it would make the ability to retain this class name essential information in Ruby. So currently, I am not positive for adding the method (not regarding the name issue). Matz. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-106316 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). Now, the name of classes and modules can be one of three things: 1. `nil` 2. Temporary 3. Permanent Maybe it would make sense to provide matching predicates, say: 1. `mod.anonymous?` 2. `mod.temporary_name?` 3. `mod.permanent_name?` so that users have an encapsulated way to check the status of the name. For example, in the Rails code base, logic like this: ```ruby @controller_path ||= name.delete_suffix("Controller").underscore unless anonymous? ``` could be rewritten as ```ruby @controller_path ||= name.delete_suffix("Controller").underscore if permanent_name? ``` What do you think? ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-107174 * Author: ioquatix (Samuel Williams) * Status: Open ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/

Issue #19742 has been updated by fxn (Xavier Noria). A KISS version of the above is to provide `permanent_name?` only, since the other two can be derived with the help `mod.name.nil?`, and I suspect that there are not a lot of cases in which you need to know if the name is exactly temporary. ---------------------------------------- Feature #19742: Introduce `Module#anonymous?` https://bugs.ruby-lang.org/issues/19742#change-107189 * Author: ioquatix (Samuel Williams) * Status: Open ---------------------------------------- As a follow-on <from https://bugs.ruby-lang.org/issues/19521>, 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/
participants (9)
-
Dan0042 (Daniel DeLorme)
-
Eregon (Benoit Daloze)
-
fxn (Xavier Noria)
-
ioquatix (Samuel Williams)
-
janosch-x
-
jeremyevans0 (Jeremy Evans)
-
ko1 (Koichi Sasada)
-
matz (Yukihiro Matsumoto)
-
rubyFeedback (robert heiler)