From: Sean O'Halpin Date: 2006-07-24T05:22:51+09:00 Subject: Re: Symbols vs. strings as hash_keys - interchangeable or not? On 7/23/06, Trans wrote: > > Sean O'Halpin wrote: > > On 7/22/06, transfire@gmail.com wrote: > > > As Ezra points out they are not the same in Ruby. A hash key can be any > > > object whatsoever. It could even be a number or another hash: > > > > > > { {:a=>1} => 'yep' } > > > > > Not meaning to be picky ;) but your example is a bit misleading. Consider: > > > > h1 = { {:a => 1} => 'nope'} > > p h1[{:a => 1}] > > #=> nil > > hk = {:a => 1} > > h2 = {hk => 'yep'} > > p h2[hk] > > #=> "yep" > > > > The problems of using hashes as keys has come up a few times - see > > e.g. ruby-talk:167185 for one solution. Or you could just use: > > Huh? I didn't know that. Why isn't one hash "eql?" to another that has > "eql?" elements? > > T. Because Hash#hash == Hash#object_id and st_lookup() uses this and eql? to test for equality (or rather inequality). At least, that's my understanding of the relevant code in st.c: #define PTR_NOT_EQUAL(table, ptr, hash_val, key) \ ((ptr) != 0 && (ptr->hash != (hash_val) || !EQUAL((table), (key), (ptr)->key))) where EQUAL is defined as: #define EQUAL(table,x,y) ((x)==(y) || (*table->type->compare)((x),(y)) == 0) I agree that it does seem a little counter-intuitive to not have Hash#eql? compare by value (like Array#eql? does). Regards, Sean