Hugh Sasse wrote: > On Fri, 16 Sep 2005, Robert Klemme wrote: > >> Hugh Sasse wrote: > >>> Hmm, that's interesting, but I don't get: >>> >>> code << "def hash() " << fields.map {|f| "self.#{f}.hash" }.join(" ^ >>> ") << " end\n" >>> >>> Shouldn't hash return a Fixnum? >> >> Definitely! >> > [...] >>> The function above appears to return a string with numbers separated >>> by " ^ ". >> >> Nope. The join appears during code generation and not during >> evaluation of the method. You can easily verify this by printing >> code after it's completed. :-) > > Oh, then it's exclusive or. I'm clearly being as sharp as a sponge > today. I'll have to remember that phrase - I could use it myself from time to time. :-) > While my brain is behaving like cottage cheese, it's probably not > the time to ask how one might guarantee that you don't stomp on the > hashes of other ojects in the system. If you have an even number of > elements, all the same Fixnum, like [1,1,1,1] then they would hash > to 0, as would [2,2], I "think". > irb(main):004:0> [1,1].inject(0) { |a,b| a ^= b.hash} > => 0 > irb(main):005:0> [2,1,1,2].inject(0) { |a,b| a ^= b.hash} > => 0 Btw, the assignment is superfluous. The result of a^b.hash is the next iteration's a. > irb(main):006:0> Yes. The algorithm can certainly be improved on. Typically you rather do something similar to (a.hash ^ (b.hash << 3) ^ (c.hash << 7)) & MAX_HASH 09:53:59 [~]: irbs >> [2,1,1,2].inject(0) { |a,b| ((a << 3) ^ b.hash) & 0xFFFF_FFFF} => 2781 >> [1,2, 1,2].inject(0) { |a,b| ((a << 3) ^ b.hash) & 0xFFFF_FFFF} => 1885 >> i.e. by shifting you make sure that order matters etc. Kind regards robert