Pergunta

Eu tenho algum código gerado automaticamente que escreve de forma eficaz sem a seguinte em um monte de lugares diferentes em algum código:

no warnings 'uninitialized';
local %ENV = %ENV;
local $/   = $/;
local @INC = @INC;
local %INC = %INC;
local $_   = $_;
local $|   = $|;
local %SIG = %SIG;
use warnings 'uninitialized';

Quando auto-geração de código, alguns argumentam que não é estritamente necessário que o código ser "bonita", mas eu gostaria de fazer aquilo para fora em uma sub-rotina. No entanto, isso seria localizar essas variáveis ??em que sub-rotina. Existe uma maneira de localizar essas variáveis ??no quadro de pilha chamando?

Atualizar : Em uma veia similar, que seria bom para ser capaz de executar eval em um quadro de pilha superior. Eu acho que Python já tem isso. Seria bom se Perl fez, também.

Foi útil?

Solução

Talvez você pode mandar para o código que usa esses moradores para ser gerados como um fecho? Então você poderia

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
});

Outras dicas

Não sei por que QuantumPete está sendo downvoted, ele parece estar certo em um presente. Você não pode dizer local para inicializar variáveis ??no bloco de chamada. Sua funcionalidade é especial, e a inicialização / desmontagem de que ele faz só funciona no bloco onde foi executado.

Existem alguns módulos experimentais como Sub :: Uplevel e Devel :: RunBlock que permitem que você tentar "tolo "caller() para sub-rotinas ou fazer um 'retorno salto em comprimento' de valores de quadros de pilha mais elevados (respectivamente), mas nenhum destes fazer nada para afetar a forma como local trata variáveis ??(eu tentei:.)

Então, por agora, ele realmente parece que você terá que viver com as declarações locais no âmbito onde você precisar deles.

Eu não sou terrivelmente familiarizado com Perl, então me perdoe se é realmente possível. Mas, normalmente, as variáveis ??locais para um quadro de pilha só estão disponíveis dentro desse quadro de pilha. Você não pode acessá-los a partir de qualquer um mais elevado ou mais baixo (a menos que você faça alguma aritmética de ponteiro hacky mas isso nunca é garantido para ter sucesso). Grandes blocos de declarações de variáveis ??são, infelizmente, algo que você vai ter que viver com.

QuantumPete

perlguts Perldoc diz:

   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. Eu não olhei para Alias.pm de perto o suficiente para ver o quão fácil isso pode ser.

Em TCL você pode usar uplevel . Quanto Perl, eu não sei.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top