From: daniel@...42.com Date: 2019-09-09T02:15:27+00:00 Subject: [ruby-core:94851] [Ruby master Feature#16153] eventually_frozen flag to gradually phase-in frozen strings Issue #16153 has been reported by Dan0042 (Daniel DeLorme). ---------------------------------------- Feature #16153: eventually_frozen flag to gradually phase-in frozen strings https://bugs.ruby-lang.org/issues/16153 * Author: Dan0042 (Daniel DeLorme) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- Freezing objects can give us a nice performance boost, but freezing previously non-frozen objects is a backward-incompatible change which is hard to handle because the place where the object is mutated can be far from where it was frozen. I propose adding a flag which gives us a migration path for freezing objects. For purposes of discussion I will call this flag "eventually_frozen". It would change the behavior of the frozen flag so that mutating the object would result in a warning instead of an error. So code like `obj = obj.dup if obj.frozen?` and `+str` would work as expected. Note that eventually_frozen strings cannot be deduplicated, as they are in reality mutable. This way it would be possible for Symbol#to_s (and many others) to return an eventually_frozen string in 2.7 which gives apps and gems time to migrate, before finally becoming a frozen deduplicated string in 3.0. This could even open up a migration path for eventually using `frozen_string_literal:true` as default. For example if it was possible to add `frozen_string_literal:eventual` to all files in a project, we could run that in production to discover where to fix things, and then change it to `frozen_string_literal:true` for a bug-free performance boost. Proposed changes: * Object#freeze(eventual:false) * if `eventual` is false * set frozen=true and eventually_frozen=false * if `eventual` is true * set frozen=true and eventually_frozen=true UNLESS frozen is already true * String#-@ * if eventually_frozen is true, deduplicate the string as if it was non-frozen * Object#frozen?(eventual:true) * if `eventual` is false * return (frozen==true and eventually_frozen==false) * if `eventual` is true * return (frozen==true) * rb_check_frozen * if eventually_frozen is true * output warning * if eventually_frozen is false and frozen is true * raise error -- https://bugs.ruby-lang.org/ Unsubscribe: