
Issue #19302 has been updated by austin (Austin Ziegler). Ruby strings are mostly copy-on-write, so `string.dup.insert(3, 'baz')` would solve the issue, and it could be written (I believe) as `-string.insert(3, 'baz')` in modern Ruby. ---------------------------------------- Feature #19302: Non-destructive String#insert https://bugs.ruby-lang.org/issues/19302#change-100957 * Author: noraj (Alexandre ZANNI) * Status: Open * Priority: Normal ---------------------------------------- It would be nice to have a non-destructive version of String#insert to be able to work with frozen literals. ## Current behavior There is only a destructive version of `String#insert` that will throw an error if the string is frozen. ```ruby irb(main):007:0> a = 'foobar'.freeze irb(main):008:0> b = a.insert(3,'baz') (irb):8:in `insert': can't modify frozen String: "foobar" (FrozenError) from (irb):8:in `<main>' from /home/noraj/.asdf/installs/ruby/3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.6.2/exe/irb:11:in `<top (required)>' from /home/noraj/.asdf/installs/ruby/3.2.0/bin/irb:25:in `load' from /home/noraj/.asdf/installs/ruby/3.2.0/bin/irb:25:in `<main>' ``` This can happen pretty quickly when you have `# frozen_string_literal: true` in all your files. ## Idea of implementation ```ruby def insert_nd(idx, str2) self[0...idx] + str2 + self[idx..] end ``` Note: this is a draft, as it doesn't handle negative index in the same way as insert ## Idea of naming Ideally the actual `String#insert` would have been `String#insert!` so that the non-destructive version could be `String#insert`, but naturally that won't do as a renaming will cause a breaking change. A more viable option would be to name it `insert_nd` (nd for non-destructive) but it's may not be following a naming convention. Another idea to avoid confusion would be to avoid using `insert` and rather use a synonym like _place_, _slip_, _slot_, _lodge_, etc. -- https://bugs.ruby-lang.org/