The following code is wrong:
sub find_stuff { my $self = shift; while (my $k = each %$self) { return $k if ($self->{$k}->{blablah}); } return undef; }
It's wrong because the function each has global side-effects: it has a global pointer for each hash it works on, and each time the method is called the loop will continue from the position where it left off previously. As such, at some point it will start after the last "stuff" we want to find and it will say the hash/object has none, though it may be full of it.

I was just bitten by this behaviour in a code that does dependency checks for RPMs — dependencies were being missed and packages failing installation due to missing dependencies.

Clearly Perl needs a way to reset each's pointer (can't be done except via keys, which moots the point). The loop in question was previously done with foreach/keys and I changed it to use each because foreach+keys were so unbearably slow on big hashes — it made a difference from waiting half a second after clicking the checkbox to install a package for the dependencies to be calculated to an almost instantaneous response when each was used.

A good optimization on foreach's performance wouldn't hurt either.

For now I'm having to do with this horrible workaround:

sub find_stuff { my $self = shift; my $first = undef; while (1) { my $r = each %$self; unless ($r) { $r = each %$self; last unless defined $r; } last if defined ($first) && $first eq $r; $first = $r unless defined $first; # do stuff quitting the loop at will } return undef; }
I could also have let the loop run to the end, putting a "next if $done" line in it, but that won't give me any guarantees either — it will leave the hash ready to be read again but fails if it receives the hash after it was read incompletely by some other code.

ESC[78;89;13p ESC[110;121;13p


In reply to Optimization, side-effects and wrong code by cbraga

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.