Posted by Seamus on Wednesday, February 29, 2012.

Beware of String#hash being used for cache keys...

Every process will have a different hash value for the same string, so cache keys based on String#hash will not work as expected!

1.9.3-p0 :001 > 'test'.hash
 => 240227015057187339 
1.9.3-p0 :002 > 'test'.hash
 => 240227015057187339 

But in another IRB session:

1.9.3-p0 :001 > 'test'.hash
 => -2779337368972820904 
1.9.3-p0 :002 > 'test'.hash
 => -2779337368972820904 

All calls to plain vanilla Object#hash have the same problem. It turns out it’s intentional…

… as explained by Yui Naruse:

It is intended. Ruby 1.9 explicitly use session local random seed to calculate a hash for strings (and some other objects).

… just not mentioned in the core Ruby docs for String#hash, which say:

Return a hash based on the string’s length and content.

There is a 7-month old pull request from FND to fix the docs… let’s hope it gets merged soon to prevent further confusion!

What blog is this?

Safety in Numbers is Brighter Planet's blog about climate science, Ruby, Rails, data, transparency, and, well, us.

Who's behind this?

We're Brighter Planet, the world's leading computational sustainability platform.

Who's blogging here?

  1. Patti Prairie CEO