Repository navigation
Thread::Mutex and three siblings answer their bare name, not the qualified one #759
Description
Measured
24 nested core classes, asked for #name and #to_s, against ruby 4.0.5 on
main @44b5067. 7 differ, in two distinct kinds.
Kind A — four classes carry their bare name instead of the qualified one
| constant | #name ruby 4.0.5 |
#name rbgo |
|---|---|---|
Thread::Mutex |
"Thread::Mutex" |
"Mutex" |
Thread::Queue |
"Thread::Queue" |
"Queue" |
Thread::SizedQueue |
"Thread::SizedQueue" |
"SizedQueue" |
Thread::ConditionVariable |
"Thread::ConditionVariable" |
"ConditionVariable" |
In MRI these are defined under Thread and additionally reachable at top
level, so the qualified spelling is the class's own name. rbgo has it the other
way round: the constant resolves under Thread:: but the class answers the bare
name, so every message that names the class is wrong.
That is observable well beyond #name:
Thread::Mutex.new.to_s # ruby "#<Thread::Mutex:0x…>" rbgo "#<Mutex:0x…>"
Thread::Mutex.new.inspect # same divergence
raise TypeError # any message built from the class nameIt also silently defeats shape tests written against the class name. #756's
Kernel#to_s fix first used self.ToS() == "#<" + classOf(self).name + ">" as
its "nothing better to say" test, and that test skipped Thread::Mutex
entirely — the value renders as #<Thread::Mutex> while its class answers
"Mutex", so the two never matched and the row kept coming out without an
address. The rule had to be made structural instead. A defect that makes
correct code fail an identity check is worth more than its own row.
Kind B — three constants are absent
Enumerator::Generator ruby Enumerator::Generator rbgo NameError
Random::Formatter ruby Random::Formatter rbgo NameError
Ractor ruby Ractor rbgo NameError
Enumerator::Generator is the interesting one: rbgo prints that name —
Enumerator.new { }.inspect gives #<Enumerator: #<Enumerator::Generator>:each>
— while the constant does not exist. So the name is a literal in a format string
rather than a class's own, and the two cannot be kept in step.
(Ractor being absent is a feature gap, not a naming one, and Random::Formatter
is a stdlib module; listing them here only because the same probe found them.)
The 17 that already agree
Thread::Backtrace, Enumerator::{Lazy,Yielder,Product,ArithmeticSequence},
Struct, Process::Status, Encoding::{Converter,CompatibilityError},
IO::Buffer, ObjectSpace::{WeakMap,WeakKeyMap}, Comparable,
Math::DomainError, Errno::ENOENT, File::Stat, Data — so the nesting
machinery is right in general, and Kind A is four specific registrations.
Reproducing
%w[Thread::Mutex Thread::Queue Thread::SizedQueue Thread::ConditionVariable].each do |n|
c = Object.const_get(n)
puts "#{n}: name=#{c.name.inspect} to_s=#{c.to_s.inspect}"
endFound while measuring #756.
🤖 Generated with Claude Code
Activity