【问题标题】:Why was the object_id for true and nil changed in ruby2.0?为什么在ruby2.0中改变了true和nil的object_id?
【发布时间】:2013-03-19 17:45:58
【问题描述】:

我在某个时候遇到了this ruby​​ object_id 分配问题,然后阅读了这个很棒的article,它讨论了 VALUE 并解释了为什么 object_id 的 true、nil 和 false 是这样的。当我发现关于 true 和 nil 的 object_id 发生明显变化时,我一直在玩弄 ruby​​2.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: true 和 nil 的值在 1.9.3 和 1.8.7 中分别为 2、4,但已更改为 20 , ruby​​2.0.0 中的 8 - 即使 false 的 id 保持不变,即 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 更改背后的原因是什么?

为什么要进行此更改?这将如何帮助开发人员?

【问题讨论】:

  • 也许他们添加了更多内部对象,所以它改变了这些值......他们不能保证是任何数字,是吗?无论如何,您可以在 ruby​​-devel 邮件列表中询问...
  • true.object_idnil.object_id 更改为什么重要?不保证它们具有任何特定值,我怀疑它们甚至可以保证在 ruby 的单独调用中是相同的。
  • 我在 windows 机器上使用 Ruby2.0,对我来说没有任何改变。
  • 似乎与“flonums”有关——一种在 64 位上加速浮点计算的技术:github.com/ruby/ruby/blob/v2_0_0_0/include/ruby/ruby.h#L383-431ruby-forum.com/topic/4404164
  • 我不敢相信三个人投票结束了这个。

标签: ruby internals ruby-2.0 objectid


【解决方案1】:

查看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,对于fixnums,最后一位是1)。其他立即数的object_ids 已更改以适应此更改。

您可以通过查看 Ruby 1.9.3 和 2.0.0 中浮点数的 object_ids 来了解这种变化。

在 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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多