I am using the # frozen_string_literal: true magic comment that RuboCop enforces by default, and I can't append something to a string:
string = 'hello'
string << ' world'
because it errors out with:
can't modify frozen String (RuntimeError)
I am using the # frozen_string_literal: true magic comment that RuboCop enforces by default, and I can't append something to a string:
string = 'hello'
string << ' world'
because it errors out with:
can't modify frozen String (RuntimeError)
You add a + before the string like:
string = +'hello'
string << ' world'
puts(string)
hello world
String.new('hello') or 'hello'.dupfrozen_string_literal is for string literal. To create a mutable String instance, use String#new or prepend a + to the string literal.
# frozen_string_literal: true
'foo'.frozen? # => true
String.new.frozen? # => false
(+'foo').frozen? # => false
When # frozen_string_literal: true is enabled, you cannot 'mutate' any strings.
Want proof? With the following script...
# frozen_string_literal: true
str = 'hello'
str << ' world'
you will get the following error...
Traceback (most recent call last):
frozen_strings.rb:4:in `<main>': can't modify frozen String (FrozenError)
'Mutate' means change the value of the object.
Therefore, your example fails because << mutates strings and it is mutating your string string since you are using the << operator.
Want proof? Go into irb! Enter the follow:
str = 'hello' # => 'hello'
obj_id1 = str.object_id # => some number, ex: 12345
str << ' world' # => 'hello world'
obj_id2 = str.object_id # => some number, ex: 12345
obj_id1 == obj_id2 # this should return true, proving that you mutated the object
However, you can get around this by using str += ' world'.
Why? Because += is a shorthand reassignment. Instead of mutating, += creates a brand new string (with a brand new object_id) and stores it under the same variable name (in this case, str).
Want Proof? Check it out in irb!
str = 'hello' # => 'hello'
obj_id1 = str.object_id # => some number, ex: 12345
str += ' world' # => ' world'
obj_id2 = str.object_id # => some other number, ex: 356456345
obj_id1 == obj_id2 # => this returns false!
Let me know if this helped!
# frozen_string_literal: true is enabled, you can 'mutate' a string by using string << 'string' instead of string += 'string' that you mentioned.ruby # frozen_string_literal: true str = 'hello' str << ' world' ``` Traceback (most recent call last): frozen_strings.rb:4:in `<main>': can't modify frozen String (FrozenError) ```# frozen_string_literal: true is enabled, but in your first comment you're asserting that you can.frozen_string_literal is set to true, if you initialize it using = +, and not simply =.