2013-03-19 37 views
13

Natknąłem się kiedyś na pytanie o przydzielenie ruby ​​object_id ruby, a następnie przeczytałem to niesamowite article, które mówi o VALUE i wyjaśnia, dlaczego object_id ma wartość true, nil i false, tak jak są one. Używam ruby2.0 object_id kiedy znalazłem widoczną zmianę, która została dokonana odnośnie object_id of true i zero.Dlaczego zmieniono object_id dla true i nil w ruby2.0?

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:Wartości prawdziwe i zero wynosiły odpowiednio 2, 4 w 1.9.3 i 1.8.7, ale zmieniono na 20, 8 ruby2.0.0 - nawet chociaż identyfikator fałszu pozostaje taki sam, tj. 0, a identyfikatory dla Fixnum zachowują ten sam stary wzór 2n + 1.

Również sposób Fixnum i Bignum realizowane są wciąż takie same w 2.0.0 jako przykład podano w wyżej wymienionym artykule prowadzi również tak samo, to używany do:

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> 

jaka jest powód zmiany tej id_obiektu?

Dlaczego wprowadzono tę zmianę? W jaki sposób pomoże to programistom?

+0

może dodali jakieś bardziej wewnętrzne obiektów, dlatego zmienił te wartości ... nie mają gwarancji, że są jakąś liczbą? W każdym razie możesz poprosić o listę mailingową ruby-devel ... – rogerdpack

+0

Dlaczego to ma znaczenie, jeśli zmieniono 'true.object_id' i' nil.object_id'? Nie mają gwarancji, że mają jakieś szczególne wartości i wątpię, że są one gwarantowane, że są takie same dla różnych wywołań 'ruby'. –

+0

Używam Ruby2.0 w maszynie Windows, dla mnie nic się nie zmieniło. –

Odpowiedz

17

Spojrzenie na Ruby source where these values are defined sugeruje, że ma to coś wspólnego z "flonums" (zobacz także commit where this was introduced). Poszukiwania "flonum" wymyśliły dyskusję na temat message on the Ruby mailing list.

Jest to technika przyspieszania obliczeń zmiennoprzecinkowych na maszynach 64-bitowych przy użyciu bezpośrednich wartości dla niektórych zmiennych zmiennoprzecinkowych, podobnie jak przy użyciu Fixnums dla liczb całkowitych. Wzorzec dla Flonums to ...xxxx xx10 (to jest ostatnie dwa bity to 10, gdzie dla ostatniego ostatniego bitu wynosi 1). object_id s innych bezpośrednich wartości zostały zmienione, aby pomieścić tę zmianę.

Możesz zobaczyć tę zmianę, patrząc na object_id s pływaków w Rubim 1.9.3 i 2.0.0.

W 1.9.3 różnych pływaków z tej samej wartości są różne obiekty:

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 

W 2.0.0 są takie same:

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