check out http://www.crusoe.net/~jeffp/articles/pm/2000-05.html

a really good document on closures...

Etienne

Jenda Krynicky wrote:

> Original suggestion (comments stripped):
> > {
> >     my $savedData = 0;
> >
> >     sub rememberData
> >     {
> >         $savedData = shift if @_;    # update with new value if given
> >         return $savedData;           # return current value
> >     }
> > }
>
> Curtis Poe <[EMAIL PROTECTED]> wrote:
> > Actually, you really don't want to try to lexically scope a subroutine
> > like that (because you can't -- well, there is a way, but it involves
> > messing with symbol tables and that's usually not a good idea).
>
> 1) He doesn't try to lexicaly scope a subroutine, but a variable ...
> so that it's only available inside the subroutine.
>
> 2) You can't LEXICALY scope a variable with ANY symbol table
> tricks ... You can hide it pretty well, but it'll be LOCAL at best, not
> LEXICAL.
>
> > Your code can easily result in mysterious "Variable $foo will not stay
> > shared" errors.  Here's a sample program to show why this is bad
> > practice (even though it looks good):
> >
> >     #!/usr/bin/perl -w
> >     use strict;
> >
> >     first( "Ovid" );
> >     second();
> >     first( "foo" );
> >
> >     sub first {
> >         my $argument = shift;
> >         second();
> >
> >         sub second {
> >             print "$argument\n";
> >         }
> >     }
> >
> > That will print "Ovid" three times and warn you that the variable
> > $argument will not stay shared.
>
> There is one IMPORTANT difference between your code and the
> original sugestion.
>
> In your code the variable in question is lexical to a subroutine,
> while in the original it's lexical to a "top-level" block.
> The important difference is that the block will only be evaluated
> once ... so it will create the lexical variable only once AND that
> instance of the variable will be remembered by the subroutine.
>
> In your code ... each time you call the outer subroutine a new
> instance of the $argument varible will be created, but the iner
> subroutine will only remember the first one.
>
> To sum this up :
>
> NEVER define a NAMED subroutine within another subroutine or a
> block that will be evaluated more than once (like a loop for
> example) !
>
> But ... the original proposal is ALL RIGHT !
>
> Jenda
>
> P.S.: If you want to share a variable between two functions do it
> like this :
>
> {
>         my $var;
>         sub fun1 { ... }
>         sub fun2 { ... }
> }
>
> NEVER like this :
>
> sub fun1 {
>         my $var;
>         ...
>         sub fun2 { ... }
> }
>
> =========== [EMAIL PROTECTED] == http://Jenda.Krynicky.cz ==========
> There is a reason for living. There must be. I've seen it somewhere.
> It's just that in the mess on my table ... and in my brain.
> I can't find it.
>                                         --- me
>
> --
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]


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

Reply via email to