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.
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.
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-forum.com/\.
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.
--
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama
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.
FWIW, JRuby is 1.8.6ish and has insertion-ordered hashes like 1.9.
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-forum.com/\.
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 Symbol
from (irb):16:in `sort'
from (irb):16
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 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
Since a hash is an unordered collection, one should not test it
according to any order. Instead test to see if a key is present and it
has certain values.
That you want it ordered should raise a red flag for you.
T.
···
On Oct 1, 2:12 pm, Ben Johnson <bjohn...@binarylogic.com> wrote:
Luis Parravicini wrote:
> On Wed, Oct 1, 2008 at 3:00 PM, Ben Johnson <bjohn...@binarylogic.com> > > wrote:
>> Is there anything out there that does this? Thanks for your help.
> Hash's == method compares if two hashes are equal (
>class Hash - RDoc Documentation)
> 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.
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 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
hsh.delete("a")
hsh.ordered_values.each do |key|
puts key
end
Does not output what you want.
There are a number of recommended packages already that should do this,
use one of them.. Not to mention this monkeypatch is going to slow down
your whole program, when you likely just need it in one or two spots.
If you do have to code it yourself, consider using the 'delegate'
library (in stdlib) to wrap your specific, non-standard logic into its
own class, where it can be managed separately from standard hashes.
Use a Dictionary from the factets gem if that's what you want.
--Ken
···
On Wed, 01 Oct 2008 14:05:33 -0500, Lex Williams wrote:
I'm guessing ruby doesn't have a LinkedHashMap kind of collection ,
right ?
--
Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/
There are a number of recommended packages already that should do this,
use one of them.. Not to mention this monkeypatch is going to slow down
your whole program, when you likely just need it in one or two spots.
If you do have to code it yourself, consider using the 'delegate'
library (in stdlib) to wrap your specific, non-standard logic into its
own class, where it can be managed separately from standard hashes.
Yours in preventing senseless monkeypatching,
-Erik
Thanks Erik, I agree 100%. I ONLY applied this when testing, where
performance really isn't an issue. I just needed hashes to iterate in a
consistent order. What was unique about my situation is that the hash
order didn't matter to the functional purpose of the method. It mattered
only when I needed to do assertions in my tests.
Honestly, if order if meaningful you should use an array. I think any of
the above gems are not the best choice when it comes to performance.
Thanks Erik, I agree 100%. I ONLY applied this when testing,
but that invalidates the tests
where
performance really isn't an issue. I just needed hashes to iterate in a
consistent order. What was unique about my situation is that the hash
order didn't matter to the functional purpose of the method. It mattered
only when I needed to do assertions in my tests.
Honestly, if order if meaningful you should use an array. I think any of
the above gems are not the best choice when it comes to performance.
arrayfields gives you both - an array with hash access
On Oct 2, 2008, at 11:05 PM, Ben Johnson wrote:
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama