From: "Eregon (Benoit Daloze)" Date: 2022-02-22T11:07:06+00:00 Subject: [ruby-core:107711] [Ruby master Feature#18597] Strings need a named method like `dup` that doesn't duplicate if receiver is mutable Issue #18597 has been updated by Eregon (Benoit Daloze). `+@`/`dup_if_immutable` semantics are only safe to use if you know you "own" the receiver and in other words it's OK to mutate it. But in that case it's also useless because if you "own" the receiver you already know it's mutable. For example think about: ```ruby NAME = "Benoit" # ... str = add_result_text(NAME, new_result) ``` This is a bug (it mutates `NAME` which should never be mutated), and hence why `dup` is more appropriate. If you do want a buffer argument, then the method should simply mutate it directly, i.e., `buffer << text`, no need for `+@`/`dup_if_immutable`. And that's why I think `dup_if_immutable` is basically useless as it's rarely if ever safe to use except when it's on a literal string, and then `str = +"foo"; str.mutate_it_some_way!` already works well enough. ---------------------------------------- Feature #18597: Strings need a named method like `dup` that doesn't duplicate if receiver is mutable https://bugs.ruby-lang.org/issues/18597#change-96634 * Author: danh337 (Dan H) * Status: Open * Priority: Normal ---------------------------------------- This is related to #16295, but focuses only on the `.+@` part. Currently we can use `.dup` in a method chain when we need to mutate a String. However there are cases where the code's context *expects* the String to be mutated. In cases like this, `.dup` always works, but we don't want to duplicate a String that is already mutable. Since `.+@` looks more like an operator, it can be unintuitive in a method chain, so this is asking for a new named method that can be used in its place, instead of always `.dup`. For example: ``` def add_result_text(buffer, new_result) text = "#{new_result.count} #{new_result.input} #{do_fancy_calc(new_result)}\n" buffer.dup_if_immutable << text # ^^^^^^^^^^^^^^^^ new method? end buffer = "" # ...maybe immutable get_lots_of_results.each do |result| buffer = add_result_text(buffer, result) # In case it was dup'ed end ``` -- https://bugs.ruby-lang.org/ Unsubscribe: