Jason Dusek wrote:

> Hi Everyone,
>
> On Friday, November 28, 2003, at 08:51  PM, drieux wrote:
> > a. how did you initialize it to begin with
> >       and why not simple re-use that solution
>
> The hash consists of filenames, line numbers and strings.
>
>         $HASH{$file}{$line} = line of code from some file.
>
> So the script goes along scouring the present directory for all
> instances of files of type '*.foo' and when it comes to one, it
> searches every last line of it for the pattern /\bfoo\b/ and if (and
> only if) there is a foo in the file, the it puts the name of the file
> in the hash, and then puts the number of each line containing /\bfoo\b/
> in the hash under the file's name, and then puts the line of code
> containing /\bfoo\b/ under the line number.  Then it prints out the
> hash and tells me what directory it was in when it did all this.
>
> So this is all fine well and good.  But let us say that I wish to
> rewrite the script so that it scours many directories in sequence, and
> then tells me what it did in each one.  There is only one thing that
> needs to be changed - each time it comes to a new directory, it should
> wipe the hash.  Then each directories report will not be contaminated
> by the previous report.  If I were to simply use the way I had
> initialized the hash in the first place, I would get a very long report
> for the last directory, most of which would be about files in other
> directories!  So I need to nuke the hash each time I go through the
> loop.
>
> - Jason

Hi Jason,

What you have here is a scoping issue. The hash for the current directory
should be declared inside the recursive function that does your scouring
work.  There is no issue then of cleaing up messes from unrelated, even if
parallel, parts of your program.  If you are designing your code properly,
this issue simply doesn't exist.  A variable scoped iside a function dies
when that function exits.  Even if the function calls itself, the variable
within each call is discrete.

Within the function below, the @$children array is much less complex than
your find results hash, but the principle applies equally.  There is a
multidimensional hash or two involved in this function also, but these are
parameters intended to work from a shared structure, so they don't speak to
the problem.


sub load_threaded_messages_to_tree {
  my ($threads, $paths, $message_list,
   $basepath, $for_path, $depth) = @_;

  my $children = [sort {$a <=> $b} keys %$threads];
  foreach my $child (@$children) {
    my $path = $basepath ? $basepath . ".$child" : $child;
    my $details = get_message_info($child);
    add_threaded_message_to_tree($path, $details,
     $message_list, $child, $for_path);
    load_threaded_messages_to_tree($threads->{$child},
     $paths, $message_list, $path, $for_path, $depth + 1);
  }
  return if not $basepath;
  if (@$children > 0) {
    $message_list->setmode($basepath, 'close');
    $message_list->close($basepath);
  } else {
    $message_list->setmode($basepath, 'none');
  }
}

What you should note here is that $children exists each time this function
calls itself.  Each time it is a new reference to an independent anonymous
array.  When each call returns the variable inside the called function
disappears, and its memory is freed.  As long as no reference to that array
is exported from the function, the garbage collection takes care of
itself.  This aint C, with its tricky "Oops, I forgot to free() my
malloc()" bugs.  Do be careful when exporting references, though.  You can
accumulate wasted memory bykeeping references to unused data structures in
scope.

Joseph


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to