From: merch-redmine@... Date: 2020-08-31T22:32:08+00:00 Subject: [ruby-core:99810] [Ruby master Bug#14895] Inconsistent constant names when using const_set on a singleton class Issue #14895 has been updated by jeremyevans0 (Jeremy Evans). Status changed from Open to Closed marcandre (Marc-Andre Lafortune) wrote in #note-5: > This looks like a bug to me. > > Here's a simplified example: > > ``` > s = Object.new.singleton_class > a = s.const_set(:A, Module.new) # => # > b = s.class_eval "module B; self end" # => #::B > c = s.const_set(:C, Module.new) # => #::C > ``` > > `a` and `c` should be treated identically. The right behavior would be for their `name` to be `#::A/C` Ruby 2.7 changed the behavior so that `a` and `c` are treated identically, but that `c` is like `a`: ``` a # # b # #::B c # # ``` I think that is sufficient for this bug to be considered closed. However, if you would like the singleton classes named, here is a patch for that: ```diff diff --git a/object.c b/object.c index 08fec850d3..1181b45b3c 100644 --- a/object.c +++ b/object.c @@ -2536,6 +2536,11 @@ rb_mod_const_set(VALUE mod, VALUE name, VALUE value) { ID id = id_for_var(mod, name, const); if (!id) id = rb_intern_str(name); + if (rb_attr_get(mod, rb_intern("__tmp_classpath__")) == Qnil && + rb_attr_get(mod, rb_intern("__classpath__")) == Qnil) { + rb_ivar_set(mod, rb_intern("__tmp_classpath__"), + rb_funcall(mod, rb_intern("to_s"), 0)); + } rb_const_set(mod, id, value); return value; ``` Output: ``` a # #>::A b # #>::B c # #>::C ``` I kind of prefer this as it shows the module is defined under a singleton class. If you like that idea, please submit a feature request for it (or switch this to a feature request and reopen). ---------------------------------------- Bug #14895: Inconsistent constant names when using const_set on a singleton class https://bugs.ruby-lang.org/issues/14895#change-87332 * Author: silver_phoenix (Pedro Pinto) * Status: Closed * Priority: Normal * ruby -v: ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux] * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- ``` irb(main):001:0> class X; end => nil irb(main):002:0> X.const_set(:Y, Module.new) => X::Y irb(main):003:0> module M; end => nil irb(main):004:0> M.const_set(:N, Module.new) => M::N irb(main):005:0> x = Object.new => # irb(main):006:0> x.singleton_class.const_set(:Z, Module.new) => # irb(main):007:0> x.singleton_class.class_eval "module A; self end" => #::A irb(main):008:0> x.singleton_class.const_set(:B, Module.new) => #::B ``` I would expect module `Z` to be named, but the modules only start being named after creating module `A` through the `module` builtin. For consistency, if module `B` is named, shouldn't module `Z` be named as well? Also happens in these ruby versions: `ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]` `ruby 2.5.1p57 (2018-03-29 revision 63029) [i386-mingw32]` -- https://bugs.ruby-lang.org/ Unsubscribe: