16

私はいつかこのrubyobject_id割り当ての質問に出くわし、次にVALUEについて説明し、object_idがtrue、nil、falseである理由を説明するこの素晴らしい記事を読みました。trueとnilのobject_idに関して行われた明らかな変更を見つけたとき、私はruby2.0object_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でしたが、ruby2.0.0では20、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の変更の背後にある理由は何ですか?

なぜこの変更が行われたのですか?これは開発者にどのように役立ちますか?

4

1 に答える 1

19

これらの値が定義されているRubyソースを見ると、これは「flonums」と関係があることがわかります(これが導入されたコミットも参照してください)。「flonum」を検索すると、Rubyメーリングリストにそれについて説明するメッセージが表示されました。

これは、整数にFixnumを使用するのと同様に、一部の浮動小数点値に即値を使用することにより、64ビットマシンでの浮動小数点計算を高速化するための手法です。Flonumのパターンは次のとおりです...xxxx xx10(つまり、最後の2ビットは10です。fixnumの場合、最後のビットはです1)。object_id他の即値のsは、この変更に対応するために変更されました。

object_idこの変更は、Ruby1.9.3および2.0.0のfloatのsを見るとわかります。

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 
于 2013-03-20T14:47:09.900 に答える