Почему object_id для true и nil изменился в ruby2.0?
Я столкнулся с этим вопросом о распределении ruby object_id когда-нибудь назад, а затем прочитал эту замечательную статью, который говорит о VALUE и объясняет, почему object_id true, nil и false так, как они есть. Я работал с ruby2.0 object_id, когда обнаружил очевидное изменение, которое было сделано в отношении object_id true и nil.
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 были соответственно 2, 4 в 1.9.3 и 1.8.7, но были изменены на 20, 8 в ruby2.0.0 - хотя идентификатор false остается тем же, что и 0, и идентификаторы для Fixnum сохраняют один и тот же старый шаблон 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>
В чем причина изменения этого объекта?
Почему было сделано это изменение? Как это поможет разработчикам?
Ответы
Ответ 1
Посмотрите на источник Ruby, где эти значения определены, предполагает, что это имеет какое-то отношение к "flonums" (также см. зафиксировать, где это было введено). Поиск "flonum" придумал сообщение в списке рассылки Ruby, обсуждая его.
Это метод ускорения вычислений с плавающей запятой на 64-битных машинах с использованием мгновенных значений для некоторых значений с плавающей запятой, аналогично использованию Fixnums для целых чисел. Шаблон для Flonums равен ...xxxx xx10
(т.е. Последние два бита 10
, где для fixnums последний бит 1
). object_id
других немедленных значений были изменены для размещения этого изменения.
Вы можете увидеть это изменение, посмотрев object_id
поплавков в Ruby 1.9.3 и 2.0.0.
В 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