2015-07-28 3 views
-1

Я написал функцию, которая выполняет итерацию по символу строки символом, вытягивая значения из хэша, используя каждый символ в качестве ключа. Значения в хэш были использованы для создания новой строки:Почему << и + = построение другой строки?

acc = '' 
str.each_char do |c| 
    acc << somehash[c] 
end 

Если строка была больше, чем один, то первый символ смотрелась бы и его хэш-значение интерполировать несколько раз во встроенной строке, которая была не то, что я хотел. Я переписал линию с << в

acc += somehash[c] 

и правильно себя вели. Почему у меня другое поведение от << и +=?

ПРИМЕЧАНИЕ. Я больше не получаю такое поведение, и мои модульные тесты проходят. Я не уверен, почему, так как я не касался логики в цикле.

+2

[ 'Струнный # <<'] (http://ruby-doc.org/core-2.2.2/String.html#method-i- 3C-3C) использует ту же строку: 'str = str + 'a'' переназначает результат только что созданному объекту строкой. Я не могу понять, как ваш код мог бы создать описанное вами поведение. – mudasobwa

+1

Честно говоря, я бы пошел с 'acc = str.chars.map {| c | somehash [c]}. join' он чище и даст тот же результат. Или еще лучше 'acc = somehash.values_at (* str.split (//)). Join' – engineersmnky

+0

@mudasobwa Да, вот что я подумал. Я всегда пользовался «<<» счастливо до сегодняшнего дня, когда мои юнит-тесты выявили странную интерполяцию. – labyrinth

ответ

5

s1 << s2 Добавляет строку s2 к s1, тогда как s1 += s2, который расширяется в s1 = s1 + s2, создает новый объект, который становится новым значением переменной s1.

Рассмотрите следующее.

s1 = "ab" 
s1.object_id #=> 70117580969460 
s2 = "cd" 

s1 << s2  #=> "abcd" 
s1   #=> "abcd" 
s1.object_id #=> 70117580969460 

Сравните с:

s1 = "ab" 
s1.object_id #=> 70117576935280 
s2 = "cd" 

s1 += s2  #=> s1 = s1 + s2 => "abcd" 
s1   #=> "abcd" 
s1.object_id #=> 70117576870900 
Смежные вопросы