Actions
Bug #19169
closedKernel#freeze doesn't propagate to singleton class when the singleton class has prepended modules
Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.2.0dev (2022-12-01T16:50:48Z master 9da2a5204f) [arm64-darwin22]
Description
a = []
singleton = a.singleton_class
a.freeze
p singleton.frozen? # => true
a = []
singleton = a.singleton_class.tap { |klass| klass.prepend(Module.new) }
a.freeze
p singleton.frozen? # => false
It's because of this function:
void
rb_freeze_singleton_class(VALUE x)
{
/* should not propagate to meta-meta-class, and so on */
if (!(RBASIC(x)->flags & FL_SINGLETON)) {
VALUE klass = RBASIC_CLASS(x);
if (klass && (klass = RCLASS_ORIGIN(klass)) != 0 &&
FL_TEST(klass, (FL_SINGLETON|FL_FREEZE)) == FL_SINGLETON) {
OBJ_FREEZE_RAW(klass);
}
}
}
It freezes the origin class of the singleton class, but I'm not sure why.
When there is no prepended modules RCLASS_ORIGIN(klass)
just returns klass
.
It's old code, so maybe the meaning of RCLASS_ORIGIN
has changed?
Practically speaking not a big deal because each time one calls .singleton_class
it copies the frozen bit of the attached object to the singleton class.
Actions
Like0
Like0Like0