Ruby - Can't Modify Frozen String (Typeerror)

Ruby - can't modify frozen string (TypeError)

since google took too long to find the right answer ...

needed to do

arg_dup = ARGV[ 0 ].dup

Can't modify frozen String error using gsub and hash

The key name is frozen so you can't modify it in place - just use gsub rather than gsub! so that it returns a modified copy of the string rather than trying to do inplace modification

operator appears to modify frozen string

Nothing is modifying your frozen String

You are re-assigning a to a new String with

a += "this string"

which is internally the same in Ruby as

a = a + "this string"

When you add two String objects in Ruby, it will create a new String containing the result (this is normal behaviour for + operator on most objects that support it). That leaves the original "Test" and "this string" values unchanged. The original, frozen String (containing "Test") will remain in memory until it is garbage collected. It can be collected because you have lost all references to it.

If you attempted to modify the object in place like this:

a << "this string"

then you should see an error message RuntimeError: can't modify frozen String

Basically, you have confused a, the local variable, with the String object to which it is pointing. Local variables can be re-assigned at any time, independently of the objects stored by Ruby. You can verify this is what has happened in your case by inspecting a.object_id before and after your a +=... line.

Getting can't modify frozen string when using string.insert

If the passed argument number is already a frozen string to start with, then number = number.to_s won't change a thing and you won't be able to modify it in place (with number.insert):

add_zeros("24".freeze, 10)  # => TypeError: can't modify frozen string

Creating a new string from it ("0#{number}") is not a problem, of course.

The reason why your string is frozen is subtle. When you use a string as a hash key, Ruby will make a copy of it and freeze it:

s = "hello"
h = {}
h[s] = :world
key = h.keys.first
key.equal?(s) # => false (Ruby made a copy)
key.frozen? # => true (Ruby automatically freezes the copy)

Anyways, as a general rule, a method should not modify its arguments.

In this case, you probably want to use rjust:

24.to_s.rjust(10, "0") # => "0000000024"

What does TypeError:can't modify frozen string mean?

Ruby allows you to freeze objects so that they may not be mutated. Either the Twitter gem froze a string and then tried to call gsub! on it, or you passed in an already-frozen string.

This answer doesn't help you solve the root of your problem, but it does answer the questions of "What does this mean and why is it happening?"



Related Topics



Leave a reply



Submit