我偶尔会遇到this ruby object_id分配问题,然后阅读这个讨论VALUE的真棒article并解释为什么object_id为true,nil和false就像它们一样。当我发现有关object_id为true和nil的明显变化时,我一直在使用ruby2.0 object_id。
forbidden:~$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
forbidden:~$
forbidden:~$ irb
irb(main):001:0> true.object_id
=> 20
irb(main):002:0> false.object_id
=> 0
irb(main):003:0> nil.object_id
=> 8
irb(main):004:0> exit
forbidden:~$
forbidden:~$ rvm use 1.9.3
Using /home/forbidden/.rvm/gems/ruby-1.9.3-p392
forbidden:~$ ruby -v
ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux]
forbidden:~$
forbidden:~$ irb
irb(main):001:0> true.object_id
=> 2
irb(main):002:0> false.object_id
=> 0
irb(main):003:0> nil.object_id
=> 4
tl; dr: 在1.9.3和1.8.7中,true和nil的值分别为2,4,但已更改为20 ,8在ruby2.0.0中 - 即使id为false仍然相同,即0和Fixnum的ID保持相同的旧2n + 1模式。
此外,Fixnum和Bignum的实现方式在2.0.0中仍然相同,因为上述文章中给出的示例也与以前的方式运行相同:
irb(main):001:0>
irb(main):002:0* ((2**62)).class
=> Bignum
irb(main):003:0> ((2**62)-1).class
=> Fixnum
irb(main):004:0>
此object_id更改背后的原因是什么?
为什么要做出这种改变?这对开发者有什么帮助?
答案 0 :(得分:18)
查看Ruby source where these values are defined表明这与“flonums”有关(另请参阅commit where this was introduced)。搜索“flonum”后,message on the Ruby mailing list进行了讨论。
这是一种通过使用某些浮点值的立即值来加速64位计算机上的浮点计算的技术,类似于使用整数的Fixnums。 Flonums的模式是...xxxx xx10
(即最后两位是10
,其中最后一位是1
。其他立即值的object_id
已更改,以适应此更改。
您可以通过查看Ruby 1.9.3和2.0.0中的object_id
个浮点数来查看此更改。
在1.9.3中,具有相同值的不同浮点数是不同的对象:
1.9.3p385 :001 > s = 10.234
=> 10.234
1.9.3p385 :002 > t = 10.234
=> 10.234
1.9.3p385 :003 > s.object_id
=> 2160496240
1.9.3p385 :004 > t.object_id
=> 2160508080
在2.0.0中它们是相同的:
2.0.0p0 :001 > s = 10.234
=> 10.234
2.0.0p0 :002 > t = 10.234
=> 10.234
2.0.0p0 :003 > s.object_id
=> 82118635605473626
2.0.0p0 :004 > t.object_id
=> 82118635605473626