1
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”变量,有没有办法使用赋值运算符(除了调用替换方法)来做到这一点?

编辑如果Ruby不允许使用赋值运算符,为什么Ruby允许使用破坏性运算符修改范围之外的变量?

4

3 回答 3

1

这两种情况是有区别的。

s.upcase!

这意味着“修改引用 s 指向的对象的状态”。

s = "DIFFERENT"

另一方面,这意味着“对 object s 的引用指向一个完全不同的对象”(或者如果您愿意,也可以“将 name s 绑定到另一个对象”)。s创建了遮蔽外部的新对象s。您无法以这种方式修改外部对象。

于 2013-02-13T06:31:00.183 回答
0

为什么 Ruby 允许修改范围之外的变量

它没有。您不修改变量,而是修改变量指向的对象。

于 2013-02-13T11:42:58.830 回答
0

您正在传递一个指向字符串对象的引用。

所以在 dos_not_modify 示例中,当被调用时,s 包含一个指向某个内存地址的指针,该地址包含字符串“abcdefg”。然后更改引用 s 的值,使其指向内存中保存新字符串“DIFFERENT”的新的不同位置。然而,调用者代码仍然继续指向原始字符串“abcdefg”的原始位置

在 dos_modify 示例中,s 包含指向某个内存地址的指针,该地址包含字符串“abcdefg”。upcase 函数直接修改这部分内存,将每个字符更改为“ABCDEFG”。调用代码指向同一个内存地址,因此在函数返回后更改会持续存在。

于 2013-02-13T06:38:39.127 回答