Ruby对象引用与集合引用

时间:2012-02-26 16:31:42

标签: ruby

我正在经历The Well Grounded Rubyist,并对以下示例感到困惑。

假设我们有一个字符串数组:

    numbers = ["one", "two", "three"]

如果我冻结此阵列,我无法执行以下操作:

    numbers[2] = "four"

该语句是运行时错误,但是:

    numbers[2].replace("four")

不是。

本书解释说,在最后两个语句的第一个中,我们正在尝试访问该数组。这就是我发现令人困惑的原因,因为我认为我们正在尝试访问数组的第三个元素,这是一个字符串对象。那与上一个陈述有何不同?

2 个答案:

答案 0 :(得分:5)

这是不同的,因为在声明中,你正在调用String#replace。正如您所料,对Array#replace 的调用将失败。

numbers.replace [1,2,3]
TypeError: can't modify frozen array

任何给定数组索引处的对象引用可能是任意复杂的,并且冻结数组的作用不是保持这些对象不被改变......它只是想保持数组不变。你可以看到这个:

ree-1.8.7> numbers[2].object_id
 => 2149301040 
ree-1.8.7> numbers[2].replace "four"
 => "four" 
ree-1.8.7> numbers[2].object_id
 => 2149301040
numbers[2]运行后,

object_id具有相同的String#replace;数组实际上没有改变。

答案 1 :(得分:0)

数组是object_id的列表。 String#replace是特殊的 - 它会更改字符串,但会保留object_id。因此,object_id的列表不会更改,并且Array不会检测到任何更改。

您可以冻结数组的每个字符串。然后,String#replace将导致错误。