2013-03-19 23 views
13

Mi sono imbattuto nello this ruby ​​object_id allocation question qualche tempo fa e poi ho letto questo fantastico article che parla di VALUE e spiega perché object_id di true, nil e false come sono. Ho iniziato a giocare con ruby2.0 object_id quando ho trovato il cambiamento apparente che è stato fatto riguardo a object_id di true e nil.Perché il valore di object_id per true e nil è cambiato in 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:I valori di vero e nil erano rispettivamente 2, 4 in 1.9.3 e 1.8.7, ma sono state modificate per 20, 8 in ruby2.0.0 - anche sebbene l'id di false rimanga lo stesso vale a dire 0 e gli id ​​per Fixnum mantengono lo stesso vecchio schema 2n + 1.

Inoltre, il modo Fixnum e bignum sono implementate è ancora lo stesso in 2.0.0 come l'esempio dato nel suddetto articolo gestisce anche lo stesso modo utilizzato per:

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> 

Qual è la motivo dietro questo cambiamento object_id?

Perché è stata apportata questa modifica? In che modo questo aiuterà gli sviluppatori?

+0

forse aggiunti alcuni oggetti più interne, in modo che cambiato questi valori ... non sono garantiti per essere un numero qualsiasi sono? Ad ogni modo potresti chiedere sulla mailing list di ruby-devel ... – rogerdpack

+0

Perché è importante se 'true.object_id' e' nil.object_id' sono cambiati? Non sono garantiti per avere valori particolari e dubito che siano anche garantiti per essere lo stesso attraverso invocazioni separate di 'ruby'. –

+0

Sto usando Ruby2.0 nella macchina Windows, per me nulla è cambiato. –

risposta

17

Uno sguardo allo Ruby source where these values are defined suggerisce che questo ha qualcosa a che fare con "flonums" (vedi anche lo commit where this was introduced). Una ricerca per "flonum" si avvicinò con un message on the Ruby mailing list discuterne.

Questa è una tecnica per accelerare i calcoli in virgola mobile su macchine a 64 bit utilizzando valori immediati per alcuni valori in virgola mobile, in modo simile all'utilizzo di Fixnum per numeri interi. Il modello per Flonums è ...xxxx xx10 (vale a dire gli ultimi due bit sono 10, dove per fixnums l'ultimo bit è 1). Gli object_id s di altri valori immediati sono stati modificati per soddisfare questa modifica.

È possibile visualizzare questo cambiamento osservando gli object_id s di float in Ruby 1.9.3 e 2.0.0.

In 1.9.3 differenti galleggianti con lo stesso valore sono oggetti differenti:

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 

In 2.0.0 sono gli stessi:

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