О Руби Гсуб - PullRequest
       18

О Руби Гсуб

1 голос
/ 07 февраля 2010
params[:hello] # => "Some params value"

hello = params[:hello]
hello.gsub!("whatever","")

params[:hello] # => ""

Не понимаю, может кто-нибудь объяснить, почему params[:hello] модифицируется gsub!? Я ожидал, что строка hello будет изменена, но не хеш params.

Ответы [ 3 ]

6 голосов
/ 07 февраля 2010

hello и params[:hello] являются ссылками на одну и ту же строку. В ruby ​​(как, например, в java и python) присваивание не копирует значение, оно просто сохраняет другую ссылку на то же значение в назначенной переменной. Поэтому, если вы явно не скопируете строку перед ее изменением (используя dup), любые изменения в строке будут влиять на все другие ссылки на строку.

2 голосов
/ 07 февраля 2010

Доступны две версии 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 не изменяет оригинал и заменяет копию.

Это общая идиома рубиновых имен методов, которые изменяют объект с помощью !.

1 голос
/ 07 февраля 2010

Если вы не хотите, чтобы он был изменен, вам нужно его клонировать, например:

hello = params[:hello].clone

То, как вы делаете это сейчас, у вас есть ссылка, а не копия.

...