UPDATE: The brilliant people at MacPorts have fixed the bug we encounter below. To upgrade:
svn checkout http://svn.macports.org/repository/macports/trunk/dports/lang/ruby/ cd ruby sudo port install
Sometimes, you find yourself using hashes as keys in a hash. It gets meta:
Item.all.group_by{ |i| i[:attrs] }
Where attrs is a hash like this:
{ :id => Fixnum, :type => String }
After a recent upgrade of some vendor code, some of us starting seeing test failures around that group_by code, and some didn't, although we were all on the same ruby version and patchlevel. The tests were still passing on the build server. And the failures made no sense -- the values of the hash were nil.
After some head-scratching, we found that Ruby running on Mac OS Leopard can't handle hashes with large numbers as values very well.
>> {:a => 536870911}.hash == {:a => 536870911}.hash
=> true
>> {:a => 536870912}.hash == {:a => 536870912}.hash
=> false
And "large numbers" are exactly what you get as default ids for fixture-created ActiveRecord objects in Rails tests. The key being assigned to and the key being read from were identical, except they weren't.
It turns out that in the Leopard environment running MacPorts the items would never have been grouped properly, but in production everything looked fine. The upgrade to Rails we made included some enhancements to Enumerable#group_by to sort the output as an OrderedHash, and that exposed us to the bug -- now, instead of just failing to group the results properly, it was breaking. Those who had recently upgraded to Snow Leopard did not have the same problem -- and our servers, obviously, were immune.
Comments