From: nobu@... Date: 2017-04-21T13:11:54+00:00 Subject: [ruby-core:80814] [Ruby trunk Bug#13397] #object_id should not be signed Issue #13397 has been updated by nobu (Nobuyoshi Nakada). vo.x (Vit Ondruch) wrote: > Is there a chance to find some generic reliable solution to this? Or is it just feature and I should persuade all the project to fix their Regexps [1] or implementation of #object_id? They seem to have the solution already. https://github.com/ruby-concurrency/concurrent-ruby/blob/master/lib/concurrent/edge/promises.rb#L1904-L1906 ```ruby def inspect "#{to_s[0..-2]} intended_time: #{@IntendedTime}>" end ``` The default `Kernel#to_s` returns a string with the class name and the object ID. ---------------------------------------- Bug #13397: #object_id should not be signed https://bugs.ruby-lang.org/issues/13397#change-64420 * 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: