How can I localize Perl variables in a different stack frame?

烈酒焚心 提交于 2019-12-02 20:24:42

Perhaps you can arrange for the code that uses those locals to be generated as a closure? Then you could

sub run_with_env {
    my ($sub, @args) = @_;
    no warnings 'uninitialized';
    local %ENV = %ENV;
    local $/   = $/;
    local @INC = @INC;
    local %INC = %INC;
    local $_   = $_;
    local $|   = $|;
    local %SIG = %SIG;
    use warnings 'uninitialized';  
    $sub->(@args);
}

run_with_env(sub {
    # do stuff here
});

run_with_env(sub {
    # do different stuff here
});

Not sure why QuantumPete is being downvoted, he seems to be right on this one. You can't tell local to initialize variables in the calling block. Its functionality is special, and the initialization/teardown that it does only works on the block where it was run.

There are some experimental modules such as Sub::Uplevel and Devel::RunBlock which allow you to attempt to "fool" caller() for subroutines or do a 'long jump return' of values to higher stack frames (respectively), but neither of these do anything to affect how local treats variables (I tried. :)

So for now, it does indeed look like you will have to live with the local declarations in the scope where you need them.

I'm not terribly familiar with Perl, so forgive me if it is actually possible. But normally, variables local to a stack frame are only available within that stack frame. You can't access them from either a higher or lower one (unless you do some hacky pointer arithmetic but that's never guaranteed to succeed). Large blocks of variable declarations are unfortunately something you will have to live with.

QuantumPete

perldoc perlguts says:

   The "Alias" module implements localization of the basic types within
   the caller's scope.  People who are interested in how to localize
   things in the containing scope should take a look there too.

FWIW. I haven't looked at Alias.pm closely enough to see how easy this might be.

Hugh Allen

In TCL you can use uplevel. As for Perl, I don't know.

JDrago

Perl has Sub::Uplevel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!