From: "Eregon (Benoit Daloze) via ruby-core" Date: 2025-12-15T11:42:36+00:00 Subject: [ruby-core:124209] [Ruby Feature#8948] Frozen regex Issue #8948 has been updated by Eregon (Benoit Daloze). Right, it's too late for 4.0, OK. > Frankly, I don't think freezing the Regexp objects is worth the effort/trouble. I already did the implementation effort so that part is fine. I think it's worth it for consistency and clean semantics, it's much better to explain "all Regexp are frozen" rather than "Regexp is partially frozen, literals are frozen, non-literals are not, but semantically a Regexp is conceptually immutable, we only kept some instances mutable for some rare gems relying on it". Also TruffleRuby already enforce all Regexps to be frozen, so it's a way to be more compatible between Ruby implementations (it's basically infeasible to support a mix of mutable & non-mutable Regexps in TruffleRuby). And of course it's also good for Ractor where then we can say "all Regexps are shareable" vs "some are, some are not". It's just cleaner overall. > Here is the code we found in the dev meeting: Thanks. The `mongo-ruby-driver` is deprecated and seems of dubious value, I think it's not a big concern. I don't understand the use-case in `wallaby-rails`, it's called `LazyRegexp` but it creates the Regexp object eagerly. Also the `@lazy_source` ivar seems to just hold the source, which can be retrieved via `Regexp#source`. mame (Yusuke Endoh) wrote in #note-31: > Also, your PR changes the behavior of `Marshal.load` for a Regexp with encoding: > > ```diff > - assert_equal(/u/, Marshal.load("\004\bI/\a\\u\000\006:\016@encoding\"\vEUC-JP")) > + assert_raise(FrozenError) { Marshal.load("\004\bI/\a\\u\000\006:\016@encoding\"\vEUC-JP") } > ``` > > This incompatibility should be fixed. Also, as a general rule, please clearly state when a PR includes such known incompatibilities. Right, I should have left a comment about it on the PR, sorry. I think that is not reasonable to support, it's actually an `@encoding` ivar on the Regexp object which has no effect on `Regexp#encoding`: ``` irb(main):001> r=Marshal.load("\004\bI/\a\\u\000\006:\016@encoding\"\vEUC-JP") => /u/ irb(main):002> r.instance_variables => [:@encoding] irb(main):003> r.encoding => # ``` Hence a FrozenError seems appropriate for that case. I would like to try this again in early 2026 / for Ruby 4.1. ---------------------------------------- Feature #8948: Frozen regex https://bugs.ruby-lang.org/issues/8948#change-115691 * Author: sawa (Tsuyoshi Sawada) * Status: Assigned * Assignee: Eregon (Benoit Daloze) ---------------------------------------- =begin I see that frozen string was accepted for Ruby 2.1, and frozen array and hash are proposed in https://bugs.ruby-lang.org/issues/8909. I feel there is even more use case for a frozen regex, i.e., a regex literal that generates a regex only once. It is frequent to have a regex within a frequently repeated portion of code, and generating the same regex each time is a waste of resource. At the moment, we can have a code like: class Foo RE1 = /pattern1/ RE2 = /pattern1/ RE3 = /pattern1/ def classify case self when RE1 then 1 when RE2 then 2 when RE3 then 3 else 4 end end end but suppose we have a frozen `Regexp` literal `//f`. Then we can write like: class Foo def classify case self when /pattern1/f then 1 when /pattern1/f then 2 when /pattern1/f then 3 else 4 end end end =end -- 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/lists/ruby-core.ml.ruby-lang.org/