+ = оператор изменяет замороженную строку
Я использую метод рубинового замораживания. Что касается определения замораживания, он замораживает значение объекта, на котором он вызывается. Мы не можем изменить значение этого объекта после него. Я должен достичь той же задачи, у меня есть объект, и я выполняю следующий код
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