http://qs321.pair.com?node_id=518339


in reply to Re^3: Spot the bug
in thread Spot the bug

The problem is people have a bad habit of forgetting to reset the iterator,
Yes, and? As long as you don't forget it in your general routine (unless you have good reason not to).
heaven help you if the general routine calls back out to uncontrolled code from inside the loop.
Yes, and? Presumably the uncontrolled code was passing in as an argument, one way or the other (otherwise, it wouldn't be uncontrolled). It's the users responsibility, just as it's the users responsibility to not pass in vital files as arguments to unlink.

Iterators hand the programmer some rope, but what doesn't? That's not a reason to avoid iterators all together.

Perl --((8:>*

Replies are listed 'Best First'.
Re^5: Spot the bug
by tlm (Prior) on Dec 21, 2005 at 16:51 UTC

    I think the problem is not with iterators as such, as much as with the fact that the scope and workings of this particular iterator are so non-obvious. In other words, it's the "magic" the bites here, IMO, not the iterator. I posted a hash iterator class some months ago that lets one create multiple simultaneous lexically-scoped iterators on any hash, but somehow it feels like overkill for most situations. Maybe this is a facility that should be built-in.

    the lowliest monk

      The each iterator is not unlike the behaviour of a filehandle where you are reading line by line. Perhaps you find that iterator non-obvious as well, and you prefer to do
      my @lines = <$file_handle>; for my $line (@lines) { ... }
      but I bet people will comment on that if you start promoting that style on Perlmonks.

      I find iterators bind to the data they act on far more natural than being binded to the location in the source code. It translates to an OO approach much more naturally.

      Perl --((8:>*

        I dont think its fair to equate each(%hash) and filehandles, the reason being that I can have multiple filehandles open on the same file without any interference problems. But with each, you have to always consider that any traversal of the hash has to be completely independent. Thus a routine that takes a filename and traverses the file calling out a callback to process each chunk is totally safe. The equivelent routine that takes a hash and traverses it using each calling out to a callback runs the serious risk that the hashes iterator will be reset or changed by user code.

        I can think of all kinds of behaviour that is totally safe with filehandles and is not safe with each(%hash). They just aren't the same thing.

        ---
        $world=~s/war/peace/g

        I think it would be better to bind lexically to the value myself. Having some code you pulled in cause side effects is definitely not what most people think of as DWIW.

        I started to try and address this issue with RFC Magic::Attach some time ago, but it fell by the way side due to outside obligations.

        -Lee

        perl digital dash (in progress)