in reply to Return values, Closure Vars from File::Find &wanted subs?

Sorry, I'm obviously not making myself clear here.
I don't want to use a Global variable.

I have a program in the form:
use strict; use File::Find; sub main; my @dirlist; main(); exit; sub main { findit(); dostuff($_) for @dirlist; } sub findit { find(\&wanted, shift(@ARGV)); } sub wanted { return unless -d $_; push(@dirlist,$File::Find::name); } sub dostuff { print "$_\n" }
and I want to do it without the global my @dirlist at the top.

I have dumped about 800 odd lines of someone's code & 60 odd subs from this example so massive rewrites aren't the order of the day but I do need to take out all these bloody global vars because they are making my life a real headache.
I'm not sure I understand why I can't just return the array from &wanted or at the very least declare it in findit and have wanted inherit it but <shrugs>.

Replies are listed 'Best First'.
Re: Sorry, Lets try the long version.
by jdporter (Paladin) on Nov 16, 2005 at 17:59 UTC

    Have you considered passing and returning data to/from these subs?

    use strict; use File::Find; main(); exit; sub main { dostuff($_) for findit( @ARGV ); } sub findit { my( $root ) = @_; my @dirlist; find( sub { -d $_ or push @dirlist, $File::Find::name; }, $root ); @dirlist } sub dostuff { print "$_\n" }

    It should be noted that the above uses a closure, which is one way to "eliminate" global variables without unduly restricting access to them.

    We're building the house of the future together.
Re: Sorry, Lets try the long version.
by Roy Johnson (Monsignor) on Nov 16, 2005 at 17:48 UTC
    You don't need to separate your variable declarations from your sub declarations. You can declare @dirlist just before the first subroutine that uses it. The declaration line will never be executed (because you exit before it gets to the declaration, so don't try to initialize it — you'd need to do that in a BEGIN block) but will be visible to the subs below it because the declaration is handled at compile time.

    For tighter scoping, you can enclose it in a block with the subs that use it (main and wanted in your example code).

    ikegami's solution shows you how to do multiple finds that don't all write to the same array. That is one of the main things closures are useful for.


    Caution: Contents may have been coded under pressure.