这种行为让我感到有些惊讶:
1.9.3-p392 :001 > n = 1
=> 1
1.9.3-p392 :002 > n.frozen?
=> false
1.9.3-p392 :003 > 1.freeze
=> 1
1.9.3-p392 :004 > n.frozen?
=> true
我尝试了frozen
的{{1}}源代码,我根本没有看到任何关于Fixnums的内容。
这种行为与非MRI Ruby实现的预期相同吗?如果我运行n = 1; 1.freeze; n.frozen?
,那么任何Ruby实现的最终结果总是true
吗?为什么或为什么不呢?
答案 0 :(得分:0)
看起来它是一个预期的功能。在Ruby Forum中,提出了一个问题:
从技术上讲,所有Fixnums都没有“冻结”(因为你无法修改状态)?
matz回答:
不是,因为fixnums可能有实例变量。
因此,从理论上讲,存在冻结固定物的空间。我不认为这是值得的。
不同的MRI Ruby版本之间似乎存在意外的不一致,但就MRI而言,它们看起来像是被识别为错误,并且已被修复。您观察到的规范似乎是预期的规范。
答案 1 :(得分:0)
由于Ruby中的所有内容都是一个对象,因此您可以冻结1
也就不足为奇了。 Symbol
具有相同的行为。正如评论中所提到的,这种行为从1.8.7(冻结没有做任何事情)变为1.9+(冻结作品)。
更令人惊讶的是冻结1
也会冻结n
。根据{{3}},
对于任何给定的实际上只有一个Fixnum对象实例 整数值
这意味着n
和1
是对同一对象的引用,修改一个将修改另一个。
您可以通过查看object_id
。
1.object_id
=> 3
n=1
n.object_id
=> 3
n.equal? 1
=> true
我在MRI 1.8.7,MRI 2.0.0,JRuby和Rubinius中尝试了这个代码并得到了相同的结果。