Hi,
Earlier tonight I tried to iterate a hash. I have somewhat thoughtlessly
been doing things like:
PMC *iter = VTABLE_get_iter(interp, some_hash);
while (VTABLE_get_bool(iter)) {
PMC *key_pmc = VTABLE_shift_pmc(interp, iter);
STRING *key = VTABLE_get_string(interp, key_pmc);
...
}
Rather than:
PMC *iter = VTABLE_get_iter(interp, some_hash);
while (VTABLE_get_bool(iter)) {
STRING *key = VTABLE_shift_string(interp, iter);
...
}
So now you're thinking "so what, Jonathan did something stupid in his
code yet again, big deal". What is perhaps surprising (well, I found it
surprising) is that if you do the first of these you only ever get the
first key in the hash - and then no more! If you do the second you'll
get all of the keys.
The whole load of hash/iterator code and the way they are so closely
tied looks kinda evil. If I'm reading it right, hash iteration ain't
threadsafe either (iterating a hash in two threads simultaneously will
run into issues); I'm not sure if that's a design goal, but anyways...
Does anyone have any thoughts on why these two code snippets do
different things, or have any reasons why they should? Or a ruling that
they shouldn't so we can decide if it's a bug...
Thanks,
Jonathan
P.S. Just for inspiration, a few comments from the current hash/iterator
code!
/* XXX int keys may be zero - use different iterator
*/
/* found next key - FIXME hash iter does auto next */
Get number of remaining elements. Does not work for hashes yet.