From: v.ondruch@... Date: 2017-04-28T13:44:56+00:00 Subject: [ruby-core:80922] [Ruby trunk Bug#13397] #object_id should not be signed Issue #13397 has been updated by vo.x (Vit Ondruch). The patch is missing documentation, otherwise I love it! ---------------------------------------- Bug #13397: #object_id should not be signed https://bugs.ruby-lang.org/issues/13397#change-64534 * Author: vo.x (Vit Ondruch) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: ruby 2.4.0p0 (2016-12-24 revision 57164) [i386-linux] * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- It is surprising that #object_id returns signed value. Let me explain show two examples. Working with 32b Ruby (ruby 2.4.0p0 (2016-12-24 revision 57164) [i386-linux]) to make this issue more apparent. ~~~ $ ruby << \EOR GC.disable 3_000_000.times { p Object.new.inspect } EOR "#" "#" "#" "#" ... snip ... "#" "#" "#" "#" "#" ^C-:2:in `p': Interrupt from -:2:in `block in
' from -:2:in `times' from -:2:in `
' "#" ~~~ In this example, the "object_id", which is part of the inspect object is unsigned, since it is printed using C sprintf with %p format. There are other libraries, which tries to mimic the output [ [1] ]. The implementation is approximately following: ~~~ $ ruby << \EOR GC.disable class A DEFAULT_OBJ_ID_STR_WIDTH = 0.size == 4 ? 7 : 14 def inspect id_str = (object_id << 1).to_s(16).rjust(DEFAULT_OBJ_ID_STR_WIDTH, '0') "#<#{self.class.name}:0x#{id_str}>" end end 3_000_000.times { p A.new.inspect } EOR "#" "#" "#" "#" "#" "#" "#" "#" ... snip ... "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" "#" ^C-:10:in `p': Interrupt from -:10:in `block in
' from -:10:in `times' from -:10:in `
' ~~~ And the output is quite surprising to me. Why the object_id should be signed value? It doesn't make any sense to me. Is this implementation wrong or is Ruby wrong? [1]: https://github.com/ruby-concurrency/concurrent-ruby/issues/547 -- https://bugs.ruby-lang.org/ Unsubscribe: