eff_i_g has asked for the wisdom of the Perl Monks concerning the following question:

Sentient saints,

I have 3 stacks: %current, %previous, and %output.

For easy debugging, I have this:

require Data::Dumper if $^P; #...lots of code... my %output; ### The information that was output last my %current; ### The current record's information my %previous; ### The previous record's information ### Now that these variables are in scope, create a closure ### that we can use for debugging. This prints all 3 stacks. my $stack = sub { print Data::Dumper->Dump( [\%previous, \%output, \%current], ['*previous', '*output', '*current'] ); };
Therefore, Data::Dumper is loaded when debugging, and a simple "x $stack->();" shows all 3 stacks.

I understand that a closure can see all of the lexicals that exist when it is defined, which leads to my question. Many lexicals exists (~50) when this closure is created. Are there any negative effects to closing around many lexicals, or is this another instance of Perl "magic" that ultimately makes no difference? Maybe I should "our" these and create a normal routine...

Thanks once again for satiating my curiosities.

Replies are listed 'Best First'.
Re: Wide open Closures?
by dave_the_m (Monsignor) on Dec 02, 2005 at 17:49 UTC
    perl 5 closures only capture those outer lexicals that are referred to within the sub.

    Dave.

      Dave, that cleared up everything! Thank you.
Re: Wide open Closures?
by samtregar (Abbot) on Dec 02, 2005 at 17:54 UTC
    I don't think you'll have a problem, but I do wonder why you'd do this instead of:

    my %stack = ( previous => \%previous, output => \%output, current => \%current );

    -sam

      Clever and cleaner Sam: Thanks :)
Re: Wide open Closures?
by revdiablo (Prior) on Dec 02, 2005 at 17:50 UTC
    Are there any negative effects to closing around many lexicals, or is this another instance of Perl "magic" that ultimately makes no difference?

    Negative effects in terms of what? You seem to want those 50 variables to hang around in memory, which the closure will do just as well as a global variable. On top of that, you get encapsulation that you don't get with a global variable. I'm not sure what would be magic, though; Perl treats one closed-over lexical variable the same as 50.

    Update: I seem to have misunderstood your question a bit. You only want those three variables to stick around? In that case, dave_the_m's comment should be particularly relevant.

    Another thing I noticed is you mention a "normal routine". Do you mean a named subroutine as opposed to an anonymous subroutine? Keep in mind named subroutines create closures too, so I'm not sure how much relevance that distinction would have.

      Yes, I was referring to named routines. Now that you mention it, I found examples of what you're speaking of in the Alpaca... and my brain keeps expanding.