You are viewing a plain text version of this content. The canonical link for it is here.
Posted to asp@perl.apache.org by "John D. Leonard II" <jo...@ce.gatech.edu> on 2002/01/21 19:21:19 UTC

Scoping question

All:

--> What is the "suggested" way to share variables across callback
functions.  My question relates to getting traversed values out of the
File::Find routine.

Below is my code.  It works, although I went through many incarnations
to get it to work properly.  Originally, I tried using "my $dirs"; but
the "sub wanted" would not update $dirs.  The only way I could get
information out of the "sub wanted" was to create this global variable.

--> Is there a better way to share the array $dirs between my may
program and my callback function &wanted?

--> Are their potential problems with the solution below?

<body>
<h1>List of files</h1>
<%

use vars qw($dirs);

sub wanted{
  push @{$dirs},$File::Find::name;
}

$dirs = [];
File::Find::find( \&wanted,"./outline" );
print @{$dirs} . " files found.";

foreach my $file (sort @$dirs){
  print "$file" . "<br>";
}

%>
</body>

Thanks,

JL


---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org


Re: Scoping question

Posted by Joshua Chamas <jo...@chamas.com>.
"John D. Leonard II" wrote:
> 
> All:
> 
> --> What is the "suggested" way to share variables across callback
> functions.  My question relates to getting traversed values out of the
> File::Find routine.
> 

Because of "my closure" problems with caching script compilations & mod_perl,
one needs to be very careful with defining callback functions, in particular
to not use a locally defined my scoped variable within it.... as in 

DO NOT DO THIS:

  my $counter;
  sub increment_counter { $counter++ };

$counter will only be defined the first script compilation, so the $counter
value will act as a global between script requests per httpd process.

I would argue that because of problems like these, one should NEVER define
a subroutine directly in an Apache::ASP script.  Such subroutines should
be moved to modules, written as includes ( which act like subs ), or use
anonymous subs instead ( see below ).

> the "sub wanted" would not update $dirs.  The only way I could get
> information out of the "sub wanted" was to create this global variable.
> 

I would do it this way too... particularly:

 use vars($global); # declare
 $global = []; # init
 sub callback { push(@$global, ...); } # use @$global

> --> Is there a better way to share the array $dirs between my may
> program and my callback function &wanted?
> 
> sub wanted{
>   push @{$dirs},$File::Find::name;
> }
> 
> $dirs = [];
> File::Find::find( \&wanted,"./outline" );
> print @{$dirs} . " files found.";
> 

This is probably the best way.  You might get away with using
a my scoped variable if you use an anonymous sub for your callback like

my $dirs = [];
my $callback = sub { push(@$dirs, $File::Find::name };
File::Find::find($callback, $dir);

The difference here is that &$callback is being redefined
each script execution, so will not cache the first $dirs from
the initial script compilation.

--Josh
_________________________________________________________________
Joshua Chamas                           Chamas Enterprises Inc.
NodeWorks Founder                       Huntington Beach, CA  USA 
http://www.nodeworks.com                1-714-625-4051

---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org