我遇到了这种引起错误或混乱的奇怪副作用。所以想象一下,这不是一个简单的例子,而是一个 gotcha 的例子。
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。
答案 0 :(得分:9)
如果我们将你的a << b << c
构造转换为更多的方法形式并抛出一堆隐含的括号,那么行为应该更清晰。重写:
greeting = "Hi there, " << name << "?"
的产率:
greeting = ("Hi there, ".<<(name)).<<("?")
String#<<
正在修改内容,但name
永远不会显示为<<
的目标/ LHS,"Hi there ," << name
字符串会执行但name
不会。如果用变量替换第一个字符串文字:
hi_there = 'Hi there, '
greeting = hi_there << name << '?'
puts hi_there
您会看到<<
已更改hi_there
;在你的"Hi there, "
案例中,这个更改是隐藏的,因为你正在修改一些你以后无法看到的东西(字符串文字)。
答案 1 :(得分:3)
你太复杂了。
操作员返回左侧,因此在第一种情况下,它只是阅读name
(因为"Hi there, " << name
首先被评估),但在第二个例子中它正在编写它。
现在,许多Ruby运算符 是右关联的,但<<
不是其中之一。请参阅:https://stackoverflow.com/a/21060235/140740
答案 2 :(得分:1)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const state = { dataRows: [], activeDataRow: {} };
const mutations = {
UPDATE_DATA(state, data) { state.dataRows = data; state.activeDataRow = {}; },
RESET_DATA(state) { state.dataRows = []; state.activeDataRow = {}; }
};
export default new Vuex.Store({ state, mutations });
的右侧从左到右进行评估。
当你做的时候
=
操作从"Hello" << name << "?"
开始,向其添加"Hello"
,然后将name
添加到变异的"?"
。
当你这样做时
"Hello"
操作以name << "?"
开头,并向其添加name
,改变名称(存在于方法的内部范围之外。
因此,在"?"
的示例中,您只是在变异one << two << three
。