我遇到了这种引起错误或混乱的奇怪副作用.所以,想象一下,这不是一个简单的例子,但的一个例子疑难杂症可能.
name = "Zorg"
def say_hello(name)
greeting = "Hi there, " << name << "?"
puts greeting
end
say_hello(name)
puts name
# Hi there, Zorg?
# Zorg
Run Code Online (Sandbox Code Playgroud)
这不会改变名称.名字还在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
Run Code Online (Sandbox Code Playgroud)
现在名字是Zorg?.疯.greeting =任务中的细微差别.Ruby在内部使用解析(?)或消息传递链接?我以为这只会像铲子一样链起来name.<<("?"),但我想这不会发生.
这就是为什么我在尝试连接时避免使用铲子操作符的原因.我一般尽量避免变异状态,但Ruby(目前)尚未针对此进行优化(尚未).也许Ruby 3会改变一切.很抱歉有关Ruby未来的范围 - 蠕变/侧面讨论.
我认为这特别奇怪,因为具有较少副作用的示例(第一个)具有两个铲操作符,其中具有更多副作用的示例具有更少的铲操作符.
更新 你是正确的DigitalRoss,我让它太复杂了.减少的例子:
one = "1"
two = "2"
three = "3"
message = one << two << three
Run Code Online (Sandbox Code Playgroud)
那你认为一切都是什么?(没有偷看!)如果我不得不猜测我会说:
one is 123
two is 23
three is 3
message is 123
Run Code Online (Sandbox Code Playgroud)
但我两个人都错了.二是2.
如果我们将你的a << b << c构造转换为更多的方法形式并抛出一堆隐含的括号,那么行为应该更清晰.重写:
greeting = "Hi there, " << name << "?"
Run Code Online (Sandbox Code Playgroud)
收益率:
greeting = ("Hi there, ".<<(name)).<<("?")
Run Code Online (Sandbox Code Playgroud)
String#<<正在修改的东西,但name永远不会作为目标/ LHS出现<<,"Hi there ," << name字符串会但name不会.如果用变量替换第一个字符串文字:
hi_there = 'Hi there, '
greeting = hi_there << name << '?'
puts hi_there
Run Code Online (Sandbox Code Playgroud)
你会看到<<改变了hi_there; 在你的"Hi there, "情况下,这个更改是隐藏的,因为你正在修改一些你以后无法看到的东西(一个字符串文字).