ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:111138] [Ruby master Bug#19169] Kernel#freeze doesn't propagate to singleton class when the singleton class has prepended modules
@ 2022-12-01 23:46 alanwu (Alan Wu)
  2022-12-02  8:24 ` [ruby-core:111145] " byroot (Jean Boussier)
  0 siblings, 1 reply; 2+ messages in thread
From: alanwu (Alan Wu) @ 2022-12-01 23:46 UTC (permalink / raw)
  To: ruby-core

Issue #19169 has been reported by alanwu (Alan Wu).

----------------------------------------
Bug #19169: Kernel#freeze doesn't propagate to singleton class when the singleton class has prepended modules
https://bugs.ruby-lang.org/issues/19169

* Author: alanwu (Alan Wu)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.2.0dev (2022-12-01T16:50:48Z master 9da2a5204f) [arm64-darwin22]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
```ruby
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:

```c
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.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [ruby-core:111145] [Ruby master Bug#19169] Kernel#freeze doesn't propagate to singleton class when the singleton class has prepended modules
  2022-12-01 23:46 [ruby-core:111138] [Ruby master Bug#19169] Kernel#freeze doesn't propagate to singleton class when the singleton class has prepended modules alanwu (Alan Wu)
@ 2022-12-02  8:24 ` byroot (Jean Boussier)
  0 siblings, 0 replies; 2+ messages in thread
From: byroot (Jean Boussier) @ 2022-12-02  8:24 UTC (permalink / raw)
  To: ruby-core

Issue #19169 has been updated by byroot (Jean Boussier).


I ran it against older rubies, and it seems like it has been behaving like this since `prepend` was introduced.

It seem to work on TruffleRuby, but not JRuby.

----------------------------------------
Bug #19169: Kernel#freeze doesn't propagate to singleton class when the singleton class has prepended modules
https://bugs.ruby-lang.org/issues/19169#change-100428

* Author: alanwu (Alan Wu)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.2.0dev (2022-12-01T16:50:48Z master 9da2a5204f) [arm64-darwin22]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
```ruby
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:

```c
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.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-12-02  8:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-01 23:46 [ruby-core:111138] [Ruby master Bug#19169] Kernel#freeze doesn't propagate to singleton class when the singleton class has prepended modules alanwu (Alan Wu)
2022-12-02  8:24 ` [ruby-core:111145] " byroot (Jean Boussier)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).