Question about hsh.each_pair

I was wondering if the hash.each_pair function messes with the order of
my hash?

I am using it to parse some text and replace html entities and
apparently it changes the order of my hash before iterating each
pairs…

Here is some example code to explain what I mean:

rep = {
“&” => “”",
“<” => “<”

}

rep.each_pair do |key, value|
text.gsub(key, value)
end

Now obviously, the substitution needs to be done in the correct order
(i.e. & needs to be parsed before <…)

But somehow, each_pair changes the order of my hash before executing the
do block, so things arent getting parsed in the correct order…

Any ideas as to why the hash seems to be re-ordered before the do block
is executed, and how I can prevent this??

On Jan 22, 2008, at 3:07 PM, Jean-nicolas Jolivet wrote:

Any ideas as to why the hash seems to be re-ordered before the do
block
is executed, and how I can prevent this??

In versions of Ruby prior to 1.9, hashes are intrinsically unordered–
you can never rely on the order of things coming out of them.

Perhaps an array or arrays might work better?

Dave

I was wondering if the hash.each_pair function messes with the order of
my hash?

It’s not the each_pair method, it’s the hash itself. Hashes are
unordered - or more specifically, ordered by the hash value of the
key, which is unrelated to the order in which you added items.

I am using it to parse some text and replace html entities and
apparently it changes the order of my hash before iterating each
pairs…
Now obviously, the substitution needs to be done in the correct order
(i.e. & needs to be parsed before <…)

Any ideas as to why the hash seems to be re-ordered before the do block
is executed, and how I can prevent this??

You could try a nested array instead
rep = [[ “&”, “”"], ["<","<"] > …]
rep.each do |key, value|
text.gsub(key, value)
end

or, maybe more simply:
require ‘CGI’
CGI.escapeHTML(text)

Thanks a lot to the 3 of you! This is exactly the information I was
looking for!

SilverTab

Alle Tuesday 22 January 2008, Jean-nicolas Jolivet ha scritto:

"&" => "&quot;",

(i.e. & needs to be parsed before <…)

But somehow, each_pair changes the order of my hash before executing the
do block, so things arent getting parsed in the correct order…

Any ideas as to why the hash seems to be re-ordered before the do block
is executed, and how I can prevent this??

Hashes in ruby don’t keep order (see the ri documentation for Hash). In
this
case, you can use a nested array:

rep = [
["&", “”"],
["<", "<],

]

or use a hash to store the pairs and an array to store the order:

rep = {
“&” => “”",
“<” => “<”

}

order = ["&", “<”, …]

then do:

order.each{|i| text.gsub(i, rep[i])}

I hope this helps

Stefano