Now, on a broader note.

Your %dependencies hash is a list, by key, of the keys that key depends on. This is inconvenient for what you're trying to do, which is why you're jumping through some hoops.

To put the function in english:

foreach key foreach dependency of that key if this dependency is the one I want to delete, delete this key continue looping continue looping

Now, note that in the middle, if you decide to delete this key, you're still continuing to loop over its dependencies. So you'd really want to break out of there.

But better, you can avoid that loop completely, and just ask the question "am I ($key) one of the elements in this array?" with grep:

if( grep { $_ eq $key } @{$dependencies{$key}} ) { print "Going to call sub for $key\n"; mydel($key); }

That saves you writing the loop.

But, let's step back. The key you're deleting probably isn't a dependency for most of the keys in the hash. If you're going to be calling this a lot, it can be a little annoying spending all that time searching over lists you're not in. You're having to do that because your list shows the dependencies of each key.

But it would be even more convenient if instead it showed the keys that depend on each key. Then you could just loop over that list, deleting stuff. And it's pretty each to build that list from the one you have. Something like:

my %requiredby; for my $key (keys $dependencies) { for my $dep (@{$dependencies{$key}}) { push @{$requiredby{$dep}}, $key; } } # Or alternately, using a statement modifier to be shorter my %requiredby; for my $key (keys %dependencies) { push @{$requiredby{$_}}, $key for @{$dependencies{$key}}; }

Now you've got a lookup you can just loop directly over, and you can get even shorter. Obviously it costs some time and memory to build that %requiredby list, but if you're going to call the delete often, it's worth it. New version (tested):

#!/usr/bin/env perl5 use strict; use warnings; my %hash = ( 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' + => 5); my %dependencies = ( 'one' => [], 'two' => [], 'three' => ['four'], 'four' => ['one','two'], 'five' => ['three'] ); my %requiredby; for my $key (keys %dependencies) { push @{$requiredby{$_}}, $key for @{$dependencies{$key}}; } sub my_del { my $thiskey = shift; # Find all the keys that depend on us, and so have to go for my $del ( @{$requiredby{$thiskey}} ) { # Recurse and delete one key that requires us print "Going to call sub for $del\n"; my_del($del); } # And finally get rid of us delete $hash{$thiskey}; print "Deleting $thiskey\n"; } my_del('one');
% ./tst.pl Going to call sub for four Going to call sub for three Going to call sub for five Deleting five Deleting three Deleting four Deleting one

Of course, won't catch infinite loops, like if we set four to depend on three as well. That's left as an exercise for the reader :)


In reply to Re: Scoping problems with recursive function by fullermd
in thread Scoping problems with recursive function by morrin

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.