# \#object\_hexid

**URL:** <https://www.ruby-forum.com/t/object-hexid/187514>\
**Category:** Ruby\
**Created:** [April 24, 2010, 3:17pm UTC](https://www.ruby-forum.com/t/object-hexid/187514 "2010-04-24T15:17:36Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 24, 2010, 3:17pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/1 "2010-04-24T15:17:36Z")

</div>

Can anyone write a reliable Kernel#object\_hexid, a method that returns  
an object’s id but in hex, just like Ruby’s normal #inspect provides.

My attempts seems to break depending on the version of Ruby used.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 24, 2010, 3:23pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/2 "2010-04-24T15:23:27Z")

</div>

On [Sat, 24.04.2010 22:16], Intransition wrote:

> Can anyone write a reliable Kernel#object\_hexid, a method that returns  
> an object’s id but in hex, just like Ruby’s normal #inspect provides.
> 
> My attempts seems to break depending on the version of Ruby used.

“0x%x” % (object\_id \<\< 1)

should work univerally, I guess.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 24, 2010, 3:31pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/3 "2010-04-24T15:31:28Z")

</div>

Thomas S. wrote:

> Can anyone write a reliable Kernel#object\_hexid, a method that returns  
> an object’s id but in hex, just like Ruby’s normal #inspect provides.
> 
> My attempts seems to break depending on the version of Ruby used.

Can you show the failing examples? Is the portability problem between  
ruby 1.8.x and 1.9.x, or are you trying to make portable with JRuby,  
Rubinius, MacRuby etc?

Is it important that object\_hexid returns the same value as reported by  
#inspect, or just some unique id?

The obvious would be something like:

> > module Kernel  
> > def object\_hexid(o)  
> > o.object\_id.to\_s(16)  
> > end  
> > end  
> > =\> nil  
> > object\_hexid(“”)  
> > =\> “3faf23593bf4”

but I’ve not tested that on any more than MRI 1.8.7, and the hex ID is  
not the same as #inspect:

> > class Foo; end  
> > =\> nil  
> > f = Foo.new  
> > =\> #Foo:0x7f5e46b1c168  
> > object\_hexid(f)  
> > =\> “3faf2358e0b4”

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 24, 2010, 4:10pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/4 "2010-04-24T16:10:52Z")

</div>

On Apr 24, 9:31 am, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thomas S. wrote:
> 
> > Can anyone write a reliable Kernel#object\_hexid, a method that returns  
> > an object’s id but in hex, just like Ruby’s normal #inspect provides.
> 
> > My attempts seems to break depending on the version of Ruby used.
> 
> Can you show the failing examples? Is the portability problem between  
> ruby 1.8.x and 1.9.x, or are you trying to make portable with JRuby,  
> Rubinius, MacRuby etc?

That would be nice.

I recently got an error report from someone using 1.8.6:

1. Failure: test\_object\_hexid(TCKernel) [./test/core/kernel/  
test\_object\_hexid.rb:8]:  
\<“#Object:0x1a14ff4”\> expected but was  
\<“#Object:0xa14ff4”\>.

I know what’s causing this in my current implementation, but I’ve been  
down this road before – I tweak the implementation to satisfy one  
error report and another seems to crop up. So I was hoping someone  
might have a definitive answer.

> Is it important that object\_hexid returns the same value as reported by  
> #inspect, or just some unique id?

Yes.

> =\> “3faf23593bf4”  
> =\> “3faf2358e0b4”  
> Right. You have to shift the value one unit like Dominik’s version.

At this point I think I am just going to go with the simple solution:

“0x” \<\< ( **id** \<\< 1).to\_s(16)

Previous error reports seem to be 1.8.6 related, and at this point I  
think I will only support 1.8.7+. Hopefully the above definition is  
consistent for all implementations. I think it would be nice if this  
method was already provided – I find it helpful in cases where I  
write a custom #inspect method, but still wish to imitate Ruby’s usual  
format.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 24, 2010, 7:55pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/5 "2010-04-24T19:55:41Z")

</div>

On 4/24/10, Intransition [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> might have a definitive answer.  
> Try this way?:

class Object  
def hexid  
Object.instance\_method(:inspect).bind(self).call[/:(.\*?)[\>]/,1]  
end  
end

Ugly, but seems like it ought to be fairly universal. Well, it won’t  
work with BlankSlate/BasicObject, but other than that…

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 24, 2010, 4:36pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/6 "2010-04-24T16:36:38Z")

</div>

On Sat, Apr 24, 2010 at 2:16 PM, Intransition [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Can anyone write a reliable Kernel#object\_hexid, a method that returns  
> an object’s id but in hex, just like Ruby’s normal #inspect provides.  
> My attempts seems to break depending on the version of Ruby used.  
> That’s something I’ve wanted when I’ve been writing #inspect for a  
> class, and  
> (for aesthetics!) I’ve wanted the object\_id encoding in the default  
> #inspect.  
> Give that there must (I assume) be a function in the underlying C or  
> Java (etc) code  
> to produce the object\_id encoding, are there any reasons why that  
> should not also  
> be a method in Object?  
> (The C code for 1.9.1 seems to encode c pointer to the object?)

On Sat, Apr 24, 2010 at 2:22 PM, Dominik H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> “0x%x” % (object\_id \<\< 1)  
> should work univerally, I guess.  
> It seems to work in Ruby 1.8.6 and 1.9.1, but not in JRuby? (See below.)

On Sat, Apr 24, 2010 at 2:31 PM, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Is it important that object\_hexid returns the same value as reported by  
> #inspect, or just some unique id?  
> I’m not sure (for me, anyway) it’s vital that it’s the same value as  
> #inspect.  
> But I’ve been wondering why (as your code showed) that the hexid in  
> #inspect  
> is different to #object\_id.to\_s(16). Can anyone give reasons?  
> (I’ve just had a quick look at the code in object.c, and a few other \*.c  
> which included object\_id or inspect/to\_s, and nothing obvious struck me.  
> I must confess I found the code not easy to follow, but I only speak  
> pidgin C.)

# code comparing the #inspect encoding of object\_id with the object\_id

class Q; end  
q = Q.new  
iid = q.inspect ; iid[-1, 1] = “” ; iid[0, 4] = “”  
oid = q.object\_id  
puts "inspect #=\> " + q.inspect  
puts "inspect id #=\> " + iid  
puts “oid \<\< 1 #=\> 0x” + (oid \<\< 1 ).to\_s(16)  
puts "Integer(iid) #=\> " + Integer(iid).to\_s  
puts "oid #=\> #=\> " + oid.to\_s

ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-mingw32]  
inspect #=\> #\<Q:0x2205b80\>  
inspect id #=\> 0x2205b80  
oid \<\< 1 #=\> 0x2205b80  
Integer(iid) #=\> 35675008  
oid #=\> #=\> 17837504

jruby 1.5.0.RC1 (ruby 1.8.7 patchlevel 249) (2010-04-14 0b08bc7)  
(Java HotSpot™ Client VM 1.6.0\_14) [x86-java]  
inspect #=\> #\<Q:0x16fdac\>  
inspect id #=\> 0x16fdac  
oid \<\< 1 #=\> 0xfb8  
Integer(iid) #=\> 1506732  
oid #=\> #=\> 2012

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 24, 2010, 8:02pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/7 "2010-04-24T20:02:43Z")

</div>

On 4/24/10, Caleb C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Try this way?:
> 
> class Object  
> def hexid  
> Object.instance\_method(:inspect).bind(self).call[/:(.\*?)[\>]/,1]  
> end  
> end
> 
> Ugly, but seems like it ought to be fairly universal. Well, it won’t  
> work with BlankSlate/BasicObject, but other than that…

Oh, but I see now that this doesn’t work for many builtins like Array,  
Hash, Integer, Float, String, true, Symbol… I didn’t expect that.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 25, 2010, 3:36pm UTC](https://www.ruby-forum.com/t/object-hexid/187514/8 "2010-04-25T15:36:43Z")

</div>

On Apr 25, 3:52 am, Charles Oliver N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> to be unique. Because of that, JRuby uses a strictly-increasing  
> class Object  
> end
> 
> > Yes.
> 
> I guarantee this won’t ever work in JRuby and may not work on anything  
> but C Ruby. I think you’re asking too much of that inspect value.
> 
> Can you describe _why_ you need this behavior?

I don’t expect the values to match up across implementations, I just  
want a reliable way to get a value for a given implementation. My only  
need is to emulate #inspect when I am customizing it. E.g.

class MyHash \<\< Hash  
def inspect  
“#\<#{self.class}:#{object\_hexid} #{super}\>”  
end  
end

So, again, there’s no need for it to match across implementations. I  
just need a method that will return whatever value the implementation  
is using.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [April 25, 2010, 9:52am UTC](https://www.ruby-forum.com/t/object-hexid/187514/9 "2010-04-25T09:52:35Z")

</div>

On Sat, Apr 24, 2010 at 9:09 AM, Intransition [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> might have a definitive answer.  
> I think you’re going to be SOL expecting these values to always match  
> up across implementations. They are fortunately the same or similar in  
> C Ruby versions because C Ruby uses the pointer address of the object  
> for that hex number. On implementations where objects can move in  
> memory, that value is almost always going to be calculated and  
> potentially not even unique.

In JRuby, the inspect value is based on the “identity hashcode” of the  
object, which is the default hashcode value the object would have it  
if did not override and provide its own hashcode. It is not guaranteed  
to be unique. Because of that, JRuby uses a strictly-increasing  
counter for object\_id’s as they are requested, and so object\_id is  
entirely unrelated to the inspect hash string.

I suspect other implementations with relocating objects will have  
similar limitations on the uniqueness and equivalence of these various  
values.

If you really want a unique hexid you can use for a given object,  
calculate it and stuff it into the object when it’s first requested:

class Object  
def hexid  
# not thread-safe, but wasting an ID isn’t a big deal  
@hexid ||= Object.calculate\_hexid  
@hexid.to\_s(16)  
end

def self.calculate\_hexid  
# appropriate mutexing should surround this  
@next\_hexid += 1  
end  
end

Or on an impl like JRuby, where object\_id is guaranteed not to produce  
a duplicate value (or at least, not up to 2^64 object\_id’s), just use  
object\_id directly.

> > Is it important that object\_hexid returns the same value as reported by  
> > #inspect, or just some unique id?
> 
> Yes.

I guarantee this won’t ever work in JRuby and may not work on anything  
but C Ruby. I think you’re asking too much of that inspect value.

Can you describe _why_ you need this behavior?

- Charlie
