2009/2/13 James C. [email protected]:
I’m really not up for a slanging match so let me just say that, in code I’ve
written, Ruby < 1.8.7 has demonstrated the behaviour I described.
This is just not true. Period. And I can prove it.
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
})
You say that in 1.8.6 the iteration order of the resulting hash has
been the same as the order in the hash literal, but look at the
following output:
puts DICTIONARY
=>
(COMMENT1)|(COMMENT2)|(STRING1)|(STRING2)|(CONDITIONAL)|(OPERATOR)|(REGEXP)
As you can see, the iteration order is completely different from the
order in the hash literal. I really don’t know what made you think
that 1.8.6 was using insertion order.
What I do know is that I’ve had code in a library released
over 2 years ago and used by a fair number of people relying on this
behaviour and heard no complaints until 1.8.7 arrived.
Your code was working by accident. Read along:
I realise that
hashtables are not ordered in 1.8 and have since made my code more robust.
You noticed that the iteration order had changed in 1.8.7, so you
changed your code to:
DICTIONARY = RegexpGroup.new.
put(:OPERATOR, /return|typeof|[[(^=,{}:;&|!?]/.source).
put(:CONDITIONAL, //*@\w|\w*@*/|//@\w*|@\w+/.source).
put(:COMMENT1, ///[^\n]/.source).
put(:COMMENT2, //*[^]*+([^/][^]*+)//.source).
put(:REGEXP,
//(\[/\]|[^/])(\.|[^/\n\])/[gim]/.source).
put(:STRING1, /'(\.|[^'\])'/.source).
put(:STRING2, /“(\.|[^”\])*"/.source)
I don’t know whether this change made a difference on 1.8.7. It
definitely had no effect on the iteration order, neither in 1.8.7 nor
in 1.8.6:
puts DICTIONARY
=>
(COMMENT1)|(COMMENT2)|(STRING1)|(STRING2)|(CONDITIONAL)|(OPERATOR)|(REGEXP)
Now you might say that on your machine and with your version of Ruby
the iteration order had been different and that in your environment
the iteration order still had been the same as the literal order. But
that is not true. Read on:
I will try to extract the code from my project that
demonstrates my point when I have some time.
No need to do that. I fixed some bugs in your code so that the
iteration order is really the same as the literal order:
puts DICTIONARY
=>
(OPERATOR)|(CONDITIONAL)|(COMMENT1)|(COMMENT2)|(REGEXP)|(STRING1)|(STRING2)
And guess what? Your code stopped working! Your code only works with
the iteration order of 1.8.6. The iteration order must be different
from insertion order, or else your code doesn’t work.
Now please stop talking about 1.8.6 having some well defined property
that has been changed in 1.8.7. This simply is not true.
I’m not the least bit interested in who’s right or wrong or in berating the
Ruby code devs or indeed anyone else, and was hoping for a productive
discussion (…)
OK. You said in a previous post that you still had one problem with
regular expressions in 1.8.7. In reality, the bug had nothing to do
with regular expressions, but with … guess what? … the iteration
order of hashes. If you carefully build all the hashes in the same
order as those you got with Ruby 1.8.6, then all your tests are
working on both 1.8.6 and 1.8.7.
I don’t know git, but if you tell me how, I can send you the two bug
fixes and the working hash sequences. I’d suggest that you take a
careful look at those sequences, whether they are as you want them to
be, because they look really weird.
Regards,
Pit