From: Justin Collins Date: 2011-02-23T16:20:00+09:00 Subject: Re: Ruby Hash Keys and Related Questions On 02/22/2011 10:42 PM, Terry Michaels wrote: > I'm still a bit new to Ruby, so humor me a bit. But I discovered today > (through trial and error) that not only can Strings, numbers, and > symbols be keys for hashes, but also any object, or even a class name! > Ruby is the first language I've used in which I would have even thought > to try that, let alone it actually working: > > > irb(main):001:0> hsh = {} > => {} > irb(main):002:0> obj = Object.new > => # > irb(main):003:0> obj2 = Object.new > => # > irb(main):004:0> hsh[obj] = "blah" > => "blah" > irb(main):005:0> hsh[obj2] = "ble" > => "ble" > irb(main):006:0> puts hsh[obj2] > ble > => nil > irb(main):007:0> puts hsh[obj1] > NameError: undefined local variable or method `obj1' for main:Object > from (irb):7 > irb(main):008:0> puts hsh[obj] > blah > => nil > irb(main):009:0> clone = obj > => # > irb(main):010:0> puts hsh[clone] > blah > => nil > irb(main):011:0> class Cl > irb(main):012:1> end > => nil > irb(main):013:0> hsh[Cl] = "blo" > => "blo" > irb(main):014:0> puts hsh[obj] > blah > => nil > irb(main):015:0> puts hsh[Cl] > blo > => nil > irb(main):016:0> class Cl2 > irb(main):017:1> end > => nil > irb(main):018:0> hsh[Cl2] = "blu" > => "blu" > irb(main):019:0> puts hsh[Cl] > blo > => nil > irb(main):020:0> puts hsh[Cl2] > blu > > Anyway, this raised a few related questions in my mind: > > 1. If the "key" taken by hash[key]= can be any object, and the key still > works even after it is aliased to another variable, does that mean that > the "key" is just a reference? > > 2. If I pass in a number, say an Integer, as a key, does Ruby actually > use the Integer? Or does it use a reference to an Integer object? > (Numbers are objects too, right?) > I am not sure the answers to these questions really "matter." As long as you put in the same key, the same value will come out. How the key is hashed to an index is a separate issue, and is handled differently depending on the key. Any object can define "hash" and "eql?" methods to control how they behave as hash keys. Try calling "hash" on a few objects to see. > 3. If I am allowed to pass in a class as a key, does that mean that > classes are objects too? If not, what exactly is being stored as the > key? > Yes, classes are objects too. > 4. When I use irb, and a line returns an object, irb shows me the > object's hexadecimal reference address (or at least, that's what it > looks like). Is there a method one can call on an object to get that > reference when one is not in irb? Just curious. Not that I know of. You can get the same output as irb by calling the "inspect" method on an object. Ruby documentation claims that the number shown is an encoded version of the object id, but the code for Object#to_s shows: VALUE rb_any_to_s(VALUE obj) { const char *cname = rb_obj_classname(obj); VALUE str; str = rb_sprintf("#<%s:%p>", cname, (void*)obj); OBJ_INFECT(str, obj); return str; } which suggests differently. But I'm not much good at reading C code. -Justin