让我们从最简单的情况开始:一个方法,它将获取一个值,其作为命名参数,并返回另一个值:
从表面上看,你可能会认为我们正在处理单个对象 ,这里:对象 x
进入 change
方法并返回同一个对象 x
。事实上,情况并非如此。一个对象进入(参数),出来的是一个不同的对象(返回值)。你可以轻松验证这一点,使用 object_id
方法以显示程序中每个对象的唯一标识数字:
num = 10
puts( "num.object_id=#{num.object_id}" )
在调用 change
方法之前和之后,变量 num
的标识符是不同的。这表明,即使变量名保持不变,change
方法返回的 num
对象也不同于发送给它的 num
对象。
在这种情况下,返回之后的 与发送到方法之前的 num
的 object_id
相同。换句话说,进入方法的对象与再次出来的对象完全相同。这产生了一个必然的结论,即在 change
方法(x += 1
)中有一些关于赋值(assignment)的行为导致创建了新的对象。
但是赋值行为本身并不能解释这个问题。如果只是为自己分配一个变量,则不会创建新对象…
num = 10
那么,如果你为对象分配的值与已有的值相同怎么办?
num = 10
通过查看 object_id
,我们可以确定当为现有的变量分配新值时,会创建一个新对象。
大多数数据项被视为是唯一的,因此一个字符串,”hello” 被认为与其它另一个字符串 “hello” 不同,以及一个浮点数 10.5 被认为与其它另一个浮点数 10.5 不同。因此,任何字符串(string)或浮点数(float)赋值操作都将创建一个新对象。
但是在处理整数(integer)时,只有当分配的值与前一个值不同时才会创建一个新对象。你可以在赋值运算符的右侧执行各种复杂的操作,但如果生成的值与原始值相同,则不会创建新对象…