Я столкнулся с этим странным побочным эффектом, который вызвал ошибку или путаницу. Итак, представьте, что это не тривиальный пример, но, возможно, пример getcha.
name = "Zorg"
def say_hello(name)
greeting = "Hi there, " << name << "?"
puts greeting
end
say_hello(name)
puts name
# Hi there, Zorg?
# Zorg
Это не изменяет имя. Имя по-прежнему Zorg
.
Но теперь посмотрим на очень тонкую разницу. в следующем примере:
name = "Zorg"
def say_hello(name)
greeting = name << "?"
puts "Hi there, #{greeting}"
end
say_hello(name)
puts name
# Hi there, Zorg?
# Zorg? <-- name has mutated
Теперь имя Zorg?
. Псих. Очень тонкая разница в назначении greeting =
. Ruby делает что-то внутренне с разбором (?) Или цепочкой передачи сообщений? Я думал, что это просто сожжет лопаты, как name.<<("?")
, но я думаю, что этого не происходит.
Вот почему я избегаю оператора лопаты при попытке выполнить конкатенацию. Обычно я стараюсь избегать мутирующего состояния, когда могу, но Ruby (в настоящее время) не оптимизирован для этого (пока). Возможно, Ruby 3 изменит ситуацию. Извините за масштабную/параллельную дискуссию о будущем Ruby.
Я думаю, что это особенно странно, так как пример с меньшими побочными эффектами (первый) имеет два оператора лопаты, где пример с большим количеством побочных эффектов имеет меньшее количество операторов лопаты.
Обновление Вы правы DigitalRoss, я делаю это слишком сложным. Уменьшенный пример:
one = "1"
two = "2"
three = "3"
message = one << two << three
Теперь, как вы думаете, все настроено? (не подглядывать!) Если бы я должен был догадаться, я бы сказал:
one is 123
two is 23
three is 3
message is 123
Но я бы ошибся в двух. Два равно 2.