+ = оператор изменяет замороженную строку

Я использую метод рубинового замораживания. Что касается определения замораживания, он замораживает значение объекта, на котором он вызывается. Мы не можем изменить значение этого объекта после него. Я должен достичь той же задачи, у меня есть объект, и я выполняю следующий код

a = "Test"
a.freeze
a += "this string"
puts a

Это дает выходы следующим образом:

Test this string
[Finished in 0.0s]

Почему это изменяет мою замороженную строку?

Ответы

Ответ 1

Ничто не изменяет ваш замороженный String

Вы перенаправляете a в новый String с помощью

a += "this string"

который внутри Ruby является таким же, как

a = a + "this string"

Когда вы добавите два объекта String в Ruby, он создаст новую String, содержащую результат (это нормальное поведение для оператора + для большинства объектов, которые его поддерживают). Это оставляет неизменным исходные значения "Test" и "this string". Исходная, замороженная строка (содержащая "Тест" ) останется в памяти до тех пор, пока не будет собран мусор. Его можно собрать, потому что вы потеряли все ссылки на него.

Если вы попытались изменить объект на месте следующим образом:

a << "this string"

тогда вы должны увидеть сообщение об ошибке RuntimeError: can't modify frozen String

В основном, вы путаете a, локальную переменную, с объектом String, на который указывает. Локальные переменные могут быть повторно назначены в любое время независимо от объектов, хранящихся в Ruby. Вы можете проверить, что это произошло в вашем случае, проверив a.object_id до и после строки a +=...

Ответ 2

Метод заморозить не позволяет вам изменять объект, он превращает объект в константу .

s1 = "its testing"
s1.freeze
puts "Object ID ===", s1.obejct_id

Итак, после замораживания объекта попытка его изменения приводит к типу Type.rror.

s1 << "testing again"

он даст, RuntimeError: не может изменить замороженную строку

НО,

freeze работает с ссылкой на объект, а не с переменной

s1 += "New Testing"
puts "Object ID ===", s1.obejct_id

будет указывать на новый объект, а также проверить его идентификатор объекта.

Для получения дополнительной информации обратитесь на этот сайт, http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html