Вопрос
params[:hello] # => "Some params value"
hello = params[:hello]
hello.gsub!("whatever","")
params[:hello] # => ""
Я не понимаю, может кто-нибудь, пожалуйста, объяснить, почему params[:hello]
модифицируется с помощью gsub!
?Я ожидал, что hello
строка, подлежащая изменению, но не params
хэш.
Решение
hello
и params[:hello]
являются ссылками на одну и ту же строку.В ruby (как, в частности, в java и python) присваивание не копирует значение, оно просто сохраняет другую ссылку на то же значение в переменной, присвоенной переменной.Поэтому, если вы явно не скопируете строку перед ее изменением (используя dup
) любые изменения в строке повлияют на все остальные ссылки на строку.
Другие советы
Существует две версии String#gsub
Доступно
a= "abc" # => "abc"
b= a.gsub("b", "2") # "a2c"
a # => "abc"
c= a.gsub!("c", "3") # => "ab3"
a # => "ab3"
String#gsub!
изменяет исходную строку и возвращает ссылку на нее.String#gsub
не изменяет оригинал и производит замену на копии.
Это распространенная идиома ruby для обозначения методов, которые изменяют объект с помощью !
.
Если вы не хотите, чтобы он изменялся, вам нужно его клонировать, например:
hello = params[:hello].clone
То, как вы делаете это сейчас, означает, что у вас есть ссылка на него, а не копия.