[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ordered hash hack for < ruby 1.9?

Ben Johnson

10/1/2008 6:00:00 PM

I am having an issue testing my code because hashes don't have a
consistent order when you iterate over them. For example, one of the
methods that I am trying to test iterates over a hash and creates a
string. That string is in a different order every time, and my tests
keep failing.

What would be perfect is if I could modify how the Hash class works so
it preserves the insert order, but only when I am testing. So I could
include this file in my tests.

Is there anything out there that does this? Thanks for your help.
--
Posted via http://www.ruby-....

21 Answers

Luis Parravicini

10/1/2008 6:08:00 PM

0

On Wed, Oct 1, 2008 at 3:00 PM, Ben Johnson <bjohnson@binarylogic.com> wrote:
> I am having an issue testing my code because hashes don't have a
> consistent order when you iterate over them. For example, one of the
> methods that I am trying to test iterates over a hash and creates a
> string. That string is in a different order every time, and my tests
> keep failing.
>
> What would be perfect is if I could modify how the Hash class works so
> it preserves the insert order, but only when I am testing. So I could
> include this file in my tests.
>
> Is there anything out there that does this? Thanks for your help.

Hash's == method compares if two hashes are equal (
http://www.ruby-doc.org/core/classes/Hash.ht... )


Bye


--
Luis Parravicini
http://ktulu.co...

Patrick Doyle

10/1/2008 6:12:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

Why not iterate over myhash.keys.sort instead of just myhash.keys?

--wpd


On Wed, Oct 1, 2008 at 2:00 PM, Ben Johnson <bjohnson@binarylogic.com>wrote:

> I am having an issue testing my code because hashes don't have a
> consistent order when you iterate over them. For example, one of the
> methods that I am trying to test iterates over a hash and creates a
> string. That string is in a different order every time, and my tests
> keep failing.
>
> What would be perfect is if I could modify how the Hash class works so
> it preserves the insert order, but only when I am testing. So I could
> include this file in my tests.
>
> Is there anything out there that does this? Thanks for your help.
> --
> Posted via http://www.ruby-....
>
>

Ben Johnson

10/1/2008 6:12:00 PM

0

Luis Parravicini wrote:
> On Wed, Oct 1, 2008 at 3:00 PM, Ben Johnson <bjohnson@binarylogic.com>
> wrote:
>> Is there anything out there that does this? Thanks for your help.
> Hash's == method compares if two hashes are equal (
> http://www.ruby-doc.org/core/classes/Hash.ht... )
>
>
> Bye

I realize that. My class is creating a hash of complex objects. For me
to create the hash by hand would take a long time and be a huge pain in
the ass. Plus this method does other things with the hash, and
ultimately returns a string. I want to test this method and it's
impossible since ruby iterates over a hash in a random order.
--
Posted via http://www.ruby-....

ara.t.howard

10/1/2008 6:13:00 PM

0


On Oct 1, 2008, at 12:00 PM, Ben Johnson wrote:

> What would be perfect is if I could modify how the Hash class works so
> it preserves the insert order, but only when I am testing. So I could
> include this file in my tests.
>
> Is there anything out there that does this? Thanks for your help.
> --


gem install orderedhash


a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Ben Johnson

10/1/2008 6:14:00 PM

0

Patrick Doyle wrote:
> Why not iterate over myhash.keys.sort instead of just myhash.keys?
>
> --wpd

Because for performance it's bad. I don't care if performance is bad in
my tests. Which is why it would be nice to alter how hashes work ONLY in
my test environment. But sorting by keys isn't smart either.

>> a = {:a => 1, :b => 2}
=> {:a=>1, :b=>2}
>> a.keys.sort
NoMethodError: undefined method `<=>' for :a:Symbol
from (irb):16:in `sort'
from (irb):16
from :0

--
Posted via http://www.ruby-....

Luis Parravicini

10/1/2008 6:15:00 PM

0

On Wed, Oct 1, 2008 at 3:07 PM, Luis Parravicini <lparravi@gmail.com> wrote:
> Hash's == method compares if two hashes are equal (
> http://www.ruby-doc.org/core/classes/Hash.ht... )

Just read again the original message and realize I didn't understand
what Ben was trying to do.
Sorry for the noise!

Bye


--
Luis Parravicini
http://ktulu.co...

Lex Williams

10/1/2008 6:24:00 PM

0

Ben Johnson wrote:
> Patrick Doyle wrote:
>> Why not iterate over myhash.keys.sort instead of just myhash.keys?
>>
>> --wpd
>
> Because for performance it's bad. I don't care if performance is bad in
> my tests. Which is why it would be nice to alter how hashes work ONLY in
> my test environment. But sorting by keys isn't smart either.
>
>>> a = {:a => 1, :b => 2}
> => {:a=>1, :b=>2}
>>> a.keys.sort
> NoMethodError: undefined method `<=>' for :a:Symbol
> from (irb):16:in `sort'
> from (irb):16
> from :0

Here's a hack for altering the original Hash class :

class Hash
alias :old_equals :[]=
attr_reader :ordered_values

def []=(key,value)
@ordered_values ||= []
@ordered_values << key
old_equals(key,value)
end


end

hsh = {}
hsh["a"]="b"
hsh["b"]="c"
hsh.ordered_values.each do |key|
puts key
end

###
outputs a,b
--
Posted via http://www.ruby-....

Lex Williams

10/1/2008 6:25:00 PM

0

That should have been called ordered_keys instead of ordered_values ...
sorry , speed coding does this to me. But,in rest,the code works .
--
Posted via http://www.ruby-....

Ben Johnson

10/1/2008 6:39:00 PM

0

Lex Williams wrote:
> That should have been called ordered_keys instead of ordered_values ...
> sorry , speed coding does this to me. But,in rest,the code works .

Awesome, this is exactly what I need, the only problem is that it
doesn't work when you do:

hsh = {"a" => "b"}

I'm trying to get this to work but having no luck.
--
Posted via http://www.ruby-....

Ben Johnson

10/1/2008 6:53:00 PM

0

Lex Williams wrote:
> That should have been called ordered_keys instead of ordered_values ...
> sorry , speed coding does this to me. But,in rest,the code works .

This seemed to do the trick for me:

class Hash
def each(&block)
sorted_keys = keys.sort { |a, b| a.to_s <=> b.to_s }
sorted_keys.each do |key|
yield key, self[key]
end
self
end
end

Thanks for your help.
--
Posted via http://www.ruby-....