I'd like to understand, what is there a reason for non-literal regexps to not being frozen, and for ranges to be?
Corresponding tickets (#16377 and #15504) doesn't clarify the reasoning:
I'm for freezing all Ranges, not only Range literals. I hate the idea of freezing only literals because casually mixing frozen and unfrozen objects leads to hard-to-debug bugs that depend upon data flow. (@mame (Yusuke Endoh) at #15504#note-3)
I understand that the matter is probably negligible, but will be very grateful for some explanations.
This is not my opinion but Matz's decision. I'm sorry if I was not clear.
I'm for freezing all Ranges, not only Range literals. I hate the idea of freezing only literals because casually mixing frozen and unfrozen objects leads to hard-to-debug bugs that depend upon data flow. (mame (Yusuke Endoh) at #15504#note-3)
This is just my opinion.
The difference of the two decisions is whether we find a real-world example affected by the changes. @ko1 (Koichi Sasada) found a real-world code that defines a singleton method on a Regexp instance in the Ruby's test framework:
And matz decided that only Regexp literals are frozen. In practical, freezing Regexps is needed for Ractors, and freezing only Regexp literals is considered useful enough for Ractors.
(I personally don't like it very much, but I'm not against the decision.)
In regards to Ranges, we don't know any real-world case affected by the change yet.
Matz said "Since there's possiblity of breakage, I'd like to experiment it." He may revert the change if someone reports any case broken by this change (before the official releases). But so far, no breakage is reported.
FWIW, I think all Regexp objects should be frozen (https://bugs.ruby-lang.org/issues/8948#note-16).
TruffleRuby will probably try this, because mixing immutable & mutable Regexps is leading to many complications when considering code sharing (e.g., multiple Ruby VMs in one process).