From: Tanaka Akira Date: 2009-02-14T12:40:07+09:00 Subject: Re: If you are unhappy with the direction of Ruby 1.8.7+, respond In article , Pit Capitain writes: > This is an excerpt from a previous version of your code: > > DICTIONARY = RegexpGroup.new({ > :OPERATOR => /return|typeof|[\[(\^=,{}:;&|!*?]/.source, > :CONDITIONAL => /\/\*@\w*|\w*@\*\/|\/\/@\w*|@\w+/.source, > :COMMENT1 => /\/\/[^\n]*/.source, > :COMMENT2 => /\/\*[^*]*\*+([^\/][^*]*\*+)*\//.source, > :REGEXP => /\/(\\[\/\\]|[^*\/])(\\.|[^\/\n\\])*\/[gim]*/.source, > :STRING1 => /\'(\\.|[^\'\\])*\'/.source, > :STRING2 => /"(\\.|[^"\\])*"/.source > }) Symbol#hash is fragile. % ruby-1.8.6p287 -e 'p :a.hash' 104738 % ruby-1.8.6p287 -e ':x; p :a.hash' 104818 The :x expression, which seems have no side-effect, affects :a.hash. This is because Symbol#hash depends on how many symbols known when the symbol first appeared. This value affects the bucket of a hash. So it affects the iteration order, until ruby 1.8. It also depends on ruby version. % all-ruby -e 'p :a.hash' ruby-1.4.6(2000-08-16) 8593 ruby-1.6.0(2000-09-19) 2281742 ruby-1.6.1(2000-09-27) 2281742 ruby-1.6.2(2000-12-25) 2291982 ruby-1.6.3(2001-03-19) 2294030 ruby-1.6.4(2001-06-04) 2294030 ruby-1.6.5(2001-09-19) 2294030 ruby-1.6.6(2001-12-26) 2296078 ruby-1.6.7(2002-03-01) 2302222 ruby-1.6.8(2002-12-24) 2308366 ruby-1.8.0(2003-08-04) 2605326 ruby-1.8.1(2003-12-25) 2609422 ruby-1.8.2(2004-12-25) 2619662 ruby-1.8.3(2005-09-21) 2625806 ruby-1.8.4(2005-12-24) 2625806 ruby-1.8.5(2006-08-25) 104018 ruby-1.8.5p52(2007-06-07) 104178 ruby-1.8.5p113(2007-09-23) 104178 ruby-1.8.5p115(2008-03-03) 104178 ruby-1.8.5p231(2008-06-20) 104178 ruby-1.8.5head(2008-06-20p231) 104178 ruby-1.8.6p0(2007-03-13) 104738 ruby-1.8.6p36(2007-06-07) 104738 ruby-1.8.6p110(2007-09-23) 104738 ruby-1.8.6p111(2007-09-24) 104738 ruby-1.8.6p114(2008-03-03) 104738 ruby-1.8.6p230(2008-06-20) 104738 ruby-1.8.6p287(2008-08-11) 104738 ruby-1.8.6head(2009-02-13p330) 104738 ruby-1.8.7p0(2008-05-31) 109218 ruby-1.8.7p17(2008-06-09) 109218 ruby-1.8.7p22(2008-06-20) 109218 ruby-1.8.7p72(2008-08-11) 109218 ruby-1.8.7head(2009-02-13p116) 109218 ruby-1.8(2009-02-05r22080) 109938 ruby-1.9.1p0(2009-01-30r21907) 117848 ruby-1.9(2009-02-14r22297) 118088 It seems ruby-1.8.7 changes the value, as well as other many versions. The changes are because the number of symbols used internally, algorithm changes, etc. Symbol#hash is fragile. Too dangerous to depend. In general, the algorithm of #hash methods (not only Symbol#hash) is ruby internal. Don't depend on that. -- Tanaka Akira