jdhedden has asked for the wisdom of the Perl Monks concerning the following question:

I have encountered a problem with using the each() function on a hash dereference of an overloaded object:
use strict; use warnings; package Results; { sub new { return (bless(\do{ my $scalar; }, __PACKAGE__)); } use overload ( '%{}' => \&as_hash ); sub as_hash { return ({ 'key1' => 'value1', 'key2' => 'value2' }); } } package main; my $obj = Results->new(); while (my ($key, $val) = each(%{$obj})) { print("$key => $val\n"); }
Running this produces an infinite loop that continually outputs only one value from the hash.

Is this a bug?

Remember: There's always one more bug.

Replies are listed 'Best First'.
Re: overload + each() bug
by borisz (Canon) on Nov 17, 2005 at 15:59 UTC
    That does not look like a bug to me. You call as_hash for each key and recreate the hash on each iteration. Rewrite as_hash like this fix this behavior.
    { my $xxx = { 'key1' => 'value1', 'key2' => 'value2' }; sub as_hash { return $xxx; } }
    Boris
      To elaborate, the problem is that the hash is recreated each time, which means the internal iterator is also recreated each time. The same behavior will show up for keys() and values(), as well.

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
        The same behavior will show up for keys() and values(), as well.
        Incorrect. keys() and values() are not iterators. They return lists composed of data from the hash argument. When used in a 'for' loop, they only get called once.
        Remember: There's always one more bug.