Como posso localizar variáveis ??Perl em um quadro de pilha diferente?
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.
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.
Perl tem Sub :: Uplevel