Feature #11782


String#+@ and String#-@

Added by ko1 (Koichi Sasada) over 5 years ago. Updated over 5 years ago.

Target version:


Matz said

In fact, my best choice is introducing String#+ that returns a mutable copy of a string.
[ruby-core:71879] [Ruby trunk - Bug #11759]

So that this is a ticket for that.
I'll commit it ASAP to check this methods before 2.3.


  • +'foo' returns modifiable string.
  • -'foo' returns frozen string (because wasters will freeze below 0 degree in Celsius).

Updated by matz (Yukihiro Matsumoto) over 5 years ago

It's OK if we don't have strong objection.


Actions #3

Updated by ko1 (Koichi Sasada) over 5 years ago

  • Status changed from Open to Closed

Applied in changeset r52917.

  • string.c: introduce String#+@ and String#-@ to control String mutability. [Feature #11782]

Updated by ko1 (Koichi Sasada) over 5 years ago

  • Status changed from Closed to Assigned

Endo-san pointed out that +foo.upcase! is evaluated as +(foo.upcase!).
It can be problem. But any practical examples?

Mutate operations such as str = +'foo' << bar << baz works (because +@ is stronger than <<).

Evaluation with current implementation (no optimization)

require 'benchmark'

N = 10_000_000{|x|{
    N.times{ 'foo'.dup }
    N.times{ +'foo' }
    N.times{ 'foo'.freeze }
    N.times{ -'foo' }

# frozen-string-literal: true
       user     system      total        real
   5.850000   0.010000   5.860000 (  5.858450)
   0.780000   0.000000   0.780000 (  0.780911)
   0.340000   0.000000   0.340000 (  0.351072)
   0.530000   0.000000   0.530000 (  0.529234)

# frozen-string-literal: false
       user     system      total        real
   2.540000   0.000000   2.540000 (  2.533344)
   0.750000   0.000000   0.750000 (  0.752019)
   0.350000   0.000000   0.350000 (  0.349776)
   1.180000   0.000000   1.180000 (  1.180882)

Updated by ko1 (Koichi Sasada) over 5 years ago

The purpose of this proposal is to encourage frozen string literals and provide better way than "foo".dup. So that String#-@ can be redundancy.

Updated by ko1 (Koichi Sasada) over 5 years ago

Quoted from DevelopersMeeting20151021Japan log:

matz: i have another idea +“...” -> mutable, -”...” -> immutable. it is more clean than “...”.freeze. how about that, instead of the magic comment? i don’t care about pull-requests, but care about the representation of source code.
akr: …
matz: I don’t like magic comment, so that I hesitate to introduce it.
a_matsuda: + and - seems string operation. << -”foo” can be seen as a here document.
matz: I understand. + and - is not good idea.
matz: another idea: make ‘’’foo’’’ frozen. incompatibility is negligible.
matz: yet another idea: make single quoted strings frozen. This is incompatible.

Matz said "+ and - is not good idea.".
So that please check it.

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 5 years ago

how about splitting strings like this?

long_string = 'first part ' +
  'second part ' +
  'last part'

Should long_string be optimized by the compiler to generate 'first part second part last part' as a frozen string, or should it actually perform the additions and generate a modified string?

Updated by bughit (bug hit) over 5 years ago

What is primary use case for -'string'? I initially though it was to be a shorthand for 'string'.freeze, avoiding allocation (due to special compiler support), producing an interned frozen string. But it does a dup, so does -'string' lack compiler support, thus first allocating a normal string then duping and freezing a copy which is not interned? So instead of 0 allocations ('string'.freeze) you get 2 (-'string')?


Also available in: Atom PDF