Руби странное поведение присваивания - PullRequest
2 голосов
/ 12 июня 2010

Это ошибка в рубине?

target_url_to_edit = target_url

if target_url_to_edit.include?("http://")
  target_url_to_edit["http://"] = ""
end

logger.debug "target url is now #{target_url}"

Возвращает target_url без http://

Ответы [ 4 ]

10 голосов
/ 12 июня 2010

Вам необходимо продублировать объект в памяти, потому что имена переменных являются просто ссылками на объекты в памяти:

target_url_to_edit = target_url.dup

Теперь target_url_to_edit получает новую копию исходного объекта.

Для вашего случая этот код, вероятно, делает то же самое в одной строке (без дублирования, если нет):

target_url_to_edit = target_url.sub(%r{^http://}, "")
5 голосов
/ 13 июня 2010

Нет, это не ошибка в Ruby, это то, как работает общее изменяемое состояние, не только в Ruby, но и на любом языке программирования.

Подумайте об этом так:моя мама зовет меня "сын", мои друзья зовут меня "Йорг".Если я постригусь, то не имеет значения, какое имя вы используете для обозначения меня: я один и тот же человек, независимо от того, называете ли вы меня "сын" или "Йорг", "мистер Миттаг" или "эй,douchebag ", поэтому мои волосы всегда будут короткими.Волшебство не вырастет, если вы будете называть меня другим именем.

В вашем коде происходит то же самое: вы ссылаетесь на строку двумя разными именами, но не имеет значения, какое имя вы используете;если строка меняется, то она меняется.

Решение, конечно, состоит в том, чтобы не использовать изменяемое состояние и не изменять общее состояние, как в ответе @ hurikhan77.

0 голосов
/ 12 июня 2010

Вот как изменить его поведение, чтобы принудительно передать значение (обратите внимание на знак звезды):

target_url_to_edit = *target_url.to_s

if target_url_to_edit.include?("http://")
  target_url_to_edit["http://"] = ""
end

logger.debug "target url is now #{target_url}"

И, как и многие вещи в ruby, трудно найти, где это задокументировано ...

0 голосов
/ 12 июня 2010

Это не ошибка. Это предполагаемое поведение, поскольку target_url_to_edit указывает на тот же объект в памяти, что и target_url, поскольку Ruby использует ссылки для назначения объекта. Если вы знаете C, это похоже на указатели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...