Richard
Richard

Reputation: 1172

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

This is a quick question. I have the following ruby code, which works fine.

  def add_zeros number, zeros
    number = number.to_s
    zeros_to_add = zeros - number.length
    zeros_to_add.times do
      number = "0#{number}"
    end
    number
  end

But if I replace

number = "0#{number}"

With

number.insert(0, "0")

Then I get TypeError: can't modify frozen string, does anyone know why this is?

Upvotes: 1

Views: 2733

Answers (1)

Marc-André Lafortune
Marc-André Lafortune

Reputation: 79562

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"

Upvotes: 1

Related Questions