in reply to Re: Perl leve control of hash iterators
in thread Perl level control of hash iterators

Just to clarify (for all respondants) I'm investigating a bug in Data::Rmap where the following loops off forever:
perl -MData::Rmap=rmap_hash -le 'rmap_hash {print keys %{$_->{a}} } ({ +a=>{1,2}})'
I'm not certain, but I suspect that the keys call interacts with this line, from Data::Rmap:
push @return, $self->_rmap($_) for values %$_;
Since the module is for general use, XS or tie-ing aren't really options. Also, $_ is aliased during the callback so that things, including hashes can be changed (sometimes leading to different disasters). This further constrains the solution space.

Thanks for your tips,

Brad

Update: I think autovivification is to blame

# added exists check perl -MData::Rmap=rmap_hash -le 'rmap_hash {print keys %{$_->{a}} if e +xists $_->{a} } ({a=>{1,2}})' 1

Replies are listed 'Best First'.
Re^3: Perl leve control of hash iterators
by diotalevi (Canon) on Feb 28, 2007 at 04:25 UTC

    Well... you'd probably better modify whatever you were given so it is read-only so the iterators *can* be reset and then you'd better do the reset/iterate-to-orig thing. Or... avoid ever using each() in Data::Rmap or take the "call arbitrary code" part out of Rmap or disallow using hashes.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^3: Perl leve control of hash iterators
by bart (Canon) on Feb 28, 2007 at 11:27 UTC
    push @return, $self->_rmap($_) for values %$_;
    Hmm, if you do this another way, you must be able to avoid the problem:
    push @return, map { $self->_rmap($_) } values %$_;
    Here, values is finished before the map even starts.

    However... you won't have a problem in the original unless the values is traversed lazily. You never know...