Stopping the scope of a lexical variable 
Author Message
 Stopping the scope of a lexical variable

        { my $x = 1;
          { CODE }
        }

COD is inside the scope of the lexical variable $x, so it can see and
change the value stored there.  Suppose I don't want that, and I want
CODE to be isolated from lexical variables in all enclosing scopes.

Actually the CODE really looke like this:

        { my $x = 1;
          { eval $something }
        }

my worry is that `$something' can affect the lexical variables.

I've been able to think of two solutions so far.  One is to use this:

        { my $x = 1;
          &isolated_eval($something);
        }

        sub isolated_eval {
          eval $_[0];
        }

but that suffers a performance hit because it takes so long to call a
function.    The other idea I had was to use this:

        { my $x = 1;
          { my $x;
            eval $something;
          }
        }

The drawback here is that I need to explicitly mask every available
lexical in the inner block, which might look a little silly.  Also I'm
worried about getting a zillion warnings about

        "my" variable $x masks earlier declaration in same scope

I hoped maybe somone else would have a clever suggestion.




Thu, 02 Aug 2001 03:00:00 GMT  
 Stopping the scope of a lexical variable

Quote:

>         { my $x = 1;
>           { CODE }
>         }

> COD is inside the scope of the lexical variable $x, so it can see and
> change the value stored there.  Suppose I don't want that, and I want
> CODE to be isolated from lexical variables in all enclosing scopes.

> Actually the CODE really looke like this:

>         { my $x = 1;
>           { eval $something }
>         }

> my worry is that `$something' can affect the lexical variables.

You seem to be looking for the "Safe" package. See "perldoc Safe".

Bye,

Jochen

--

"How could this be a problem in a country where            +49 7123 14887
we have Intel and Microsoft?" (Al Gore, Vanity Fair,
January 1999 issue, talking about Y2K)



Fri, 03 Aug 2001 03:00:00 GMT  
 Stopping the scope of a lexical variable

Quote:
> You seem to be looking for the "Safe" package. See "perldoc Safe".

That's a good suggestion, but I don't think I can use `Safe' here.
That is because the function looks something like this:

        sub myfunc {

          my $safe = $args{SAFE};
          my $code = $args{CODE};
          my $x = 1;

          if (defined $safe) {
            $safe->reval($code);
          } else {
            eval $code;               # ***
          }
        }

        # The actual code is much longer and more complicated, of course.

I am looking for a trick I can use at the line (***), which is the
code path followed when the user did not enable the `SAFE' option.
Safe has somewhat different behavior from non-Safe.  For example,  the
user might want to set variables in the $code, and be able to see the
changes in the main program after the $code is executed; this won't
happen with `Safe'.  So I don't want to use `Safe' here, because it
was not what the user asked for.

Do you have any other ideas?



Fri, 03 Aug 2001 03:00:00 GMT  
 Stopping the scope of a lexical variable

Quote:

> I am looking for a trick I can use at the line (***), which is the
> code path followed when the user did not enable the `SAFE' option.
> Safe has somewhat different behavior from non-Safe.  For example,  the
> user might want to set variables in the $code, and be able to see the
> changes in the main program after the $code is executed; this won't
> happen with `Safe'.  So I don't want to use `Safe' here, because it
> was not what the user asked for.

So far I see nothing that can't be done via "Safe". Of course you need
some possibility, to tell the system which variables you want to share.
I typically use a hash ref %common for such things and share this
between the Safe compartment and the calling namespace.

Bye,

Jochen

--

"How could this be a problem in a country where            +49 7123 14887
we have Intel and Microsoft?" (Al Gore, Vanity Fair,
January 1999 issue, talking about Y2K)



Fri, 03 Aug 2001 03:00:00 GMT  
 Stopping the scope of a lexical variable

Jochen Wiedmann:

Quote:
> So far I see nothing that can't be done via "Safe".

Nevertheless, it is not suitable for my application.


Fri, 03 Aug 2001 03:00:00 GMT  
 Stopping the scope of a lexical variable
The following message is a courtesy copy of an article
that has been posted as well.

Quote:

>    { my $x = 1;
>      { CODE }
>    }

> COD is inside the scope of the lexical variable $x, so it can see and
> change the value stored there.  Suppose I don't want that, and I want
> CODE to be isolated from lexical variables in all enclosing scopes.

My suggestion might not be very clean, but I think it does what you
want. Change all lexicals to locals and change the package:

        {
           local $x = 1;
           {
              package Dummy;
              CODE;
           }
        }

Ala



Fri, 03 Aug 2001 03:00:00 GMT  
 Stopping the scope of a lexical variable

Quote:
> My suggestion might not be very clean, but I think it does what you
> want. Change all lexicals to locals and change the package:

>    {
>       local $x = 1;
>       {
>          package Dummy;
>               CODE;
>            }
>    }

Thanks for reminding me of this.  In an older version of the package, I
had a note in the TODO file that said

        C<my> variables are still susceptible to being clobbered...
        Perhaps it will be safer to make them C<local> variables.

I had forgotten all about it.  In my case works out to something like
this:

        package MJDs::Package;
        { local $x = 1;
          eval 'package DUMMY; ' . $CODE:
        }

Of course, the evaluated code can still reach into the calling package
and modify the `local' variables.  So it's not clear whether it's
better to use the technique you suggested, or just go with lexical
variables and give them funny names, ilke this:

        package MJDs::Package;
        { my $MJDs__Package__x;
          eval "package DUMMY; " . $CODE:
        }

In the former case, the $CODE can modify the variable via
$MJDs::Package::x, and in the latter case it can modify the variable via
$MJDs__Package__x.  The difference between these seems minimal, and my
(slight) preference was for the second one, so that's what I did do.



Fri, 03 Aug 2001 03:00:00 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Lexical Variable Scope

2. Scope of a global lexical

3. Lexical scope bug in eval()?

4. How to give $SIG{__WARN__} lexical scope?

5. Lexical scope and embedded subroutines.

6. my, local and lexical scope

7. lexical scope, symbolic refs and grandfathering

8. BUG, sorting lexical scope array, perl5.001m

9. FAQ 7.18 How can I access a dynamic variable while a similarly named lexical is in scope?

10. FAQ 7.18 How can I access a dynamic variable while a similarly named lexical is in scope?

11. FAQ 7.18 How can I access a dynamic variable while a similarly named lexical is in scope?

12. FAQ 7.18 How can I access a dynamic variable while a similarly named lexical is in scope?

 

 
Powered by phpBB® Forum Software