class PassByValueScopeConfusion
def does_not_modify(s)
s = "DIFFERENT"
end
def does_modify(s)
s.upcase!
end
end
obj = PassByValueScopeConfusion.new
some_string = "abcdefg"
# does not change the value of some_string
obj.does_not_modify(some_string)
# changes the value of some_string
obj.does_modify(some_string)
我将一个字符串传递给一个方法,该方法在传入的字符串中调用破坏性方法,不知何故,原始变量“some_string”被修改。如果我能够使用破坏性方法修改范围之外的“some_string”变量,是否有办法使用赋值运算符(除了调用replace方法之外)?
编辑如果Ruby不允许使用赋值运算符,为什么Ruby允许使用破坏性运算符修改范围之外的变量?
答案 0 :(得分:1)
这两种情况之间存在差异。
s.upcase!
这意味着“修改引用s所指向的对象的状态”。
s = "DIFFERENT"
另一方面,这意味着“将对象的引用指向一个完全不同的对象”(或“如果您愿意,将名称绑定到另一个对象”)。创建了新对象s
,该对象遮蔽了外部s
。你无法以这种方式修改外部对象。
答案 1 :(得分:0)
您正在传入指向字符串对象的引用。
因此在do_not_modify示例中,当调用时,s包含指向包含字符串“abcdefg”的某个内存地址的指针。然后,您可以将引用的值更改为指向内存中保存新字符串“DIFFERENT”的新的不同位置。然而,调用者代码仍然继续指向原始字符串“abcdefg”的原始位置
在does_modify示例中,s包含指向包含字符串“abcdefg”的某个内存地址的指针。 upcase函数直接修改这部分内存并将每个字符更改为“ABCDEFG”。调用代码指向同一个内存地址,因此在函数返回后会保持更改。
答案 2 :(得分:0)
为什么Ruby允许修改范围之外的变量
没有。您不修改变量,而是修改变量指向的对象。