Hashes do not preserve insertion order. In other words, it is
simply a fluke that your examples #1 and #2 print out the hash
keys in the correct order; they are the exception rather than
the rule.
If you just want the keys sorted alphabetically, use
for my $k (sort keys %GRAMMAR) {
But you may run into situations where you really do want to
preserve insertion order, and it's not just a matter of sorting
alphabetically.
If you want to preserve insertion order and still use a hash,
take a look at Tie::IxHash. Or, if you're not wedded to
a hash, you could always use an array, and push array refs
onto your list of grammars:
push @GRAMMAR, [ $1, $2 ];
And then when iterating:
for my $rec (@GRAMMAR) {
print $rec->[0], "\n";
}
BTW, when you do a regex match w/ capturing parens, you
really should check whether the regex successfully matches:
next unless /([A-Z]) -> (.*)/;
$GRAMMAR{$1} = $2;
That way, if the regex fails--ie. the line you're looking at doesn't
match that regex--you'll just skip that line. You don't want to use
$1 and $2 if the match was unsuccessful, because there's no
telling what they could contain. :)