Pregunta

Tengo un código generado automáticamente que efectivamente escribe lo siguiente en un montón de lugares diferentes en algún código:

no warnings 'uninitialized';
local %ENV = %ENV;
local $/   = $/;
local @INC = @INC;
local %INC = %INC;
local 

Tengo un código generado automáticamente que efectivamente escribe lo siguiente en un montón de lugares diferentes en algún código:

<*>

Cuando se genera automáticamente el código, algunos argumentan que no es estrictamente necesario que el código sea `` hermoso '', pero me gustaría llevarlo a una subrutina. Sin embargo, eso localizaría esas variables en esa subrutina. ¿Hay alguna manera de localizar esas variables en el marco de la pila de llamadas?

Actualización : en una línea similar, sería bueno poder ejecutar eval en un marco de pila más alto. Creo que Python ya tiene esto. Sería bueno si Perl también lo hiciera.

=

Tengo un código generado automáticamente que efectivamente escribe lo siguiente en un montón de lugares diferentes en algún código:

<*>

Cuando se genera automáticamente el código, algunos argumentan que no es estrictamente necesario que el código sea `` hermoso '', pero me gustaría llevarlo a una subrutina. Sin embargo, eso localizaría esas variables en esa subrutina. ¿Hay alguna manera de localizar esas variables en el marco de la pila de llamadas?

Actualización : en una línea similar, sería bueno poder ejecutar eval en un marco de pila más alto. Creo que Python ya tiene esto. Sería bueno si Perl también lo hiciera.

; local $| = $|; local %SIG = %SIG; use warnings 'uninitialized';

Cuando se genera automáticamente el código, algunos argumentan que no es estrictamente necesario que el código sea `` hermoso '', pero me gustaría llevarlo a una subrutina. Sin embargo, eso localizaría esas variables en esa subrutina. ¿Hay alguna manera de localizar esas variables en el marco de la pila de llamadas?

Actualización : en una línea similar, sería bueno poder ejecutar eval en un marco de pila más alto. Creo que Python ya tiene esto. Sería bueno si Perl también lo hiciera.

¿Fue útil?

Solución

¿Quizás pueda organizar el código que usa esos locales para ser generado como cierre? Entonces podrías

sub run_with_env {
    my ($sub, @args) = @_;
    no warnings 'uninitialized';
    local %ENV = %ENV;
    local $/   = $/;
    local @INC = @INC;
    local %INC = %INC;
    local 

¿Quizás pueda organizar el código que usa esos locales para ser generado como cierre? Entonces podrías

<*> =

¿Quizás pueda organizar el código que usa esos locales para ser generado como cierre? Entonces podrías

<*>; local $| = $|; local %SIG = %SIG; use warnings 'uninitialized'; $sub->(@args); } run_with_env(sub { # do stuff here }); run_with_env(sub { # do different stuff here });

Otros consejos

No estoy seguro de por qué QuantumPete está siendo rechazado, parece estar en lo cierto en este caso. No puede decirle a local que inicialice variables en el bloque de llamada. Su funcionalidad es especial, y la inicialización / desmontaje que hace solo funciona en el bloque donde se ejecutó.

Hay algunos módulos experimentales como Sub :: Uplevel y Devel :: RunBlock que le permiten intentar " tonto " caller () para subrutinas o hacer un 'retorno de salto largo' de valores a marcos de pila más altos (respectivamente), pero ninguno de estos hace nada para afectar la forma en que local trata las variables ( Lo intenté. :)

Entonces, por ahora, parece que tendrá que vivir con las declaraciones locales en el ámbito donde las necesita.

No estoy muy familiarizado con Perl, así que perdóname si es posible. Pero normalmente, las variables locales a un marco de pila solo están disponibles dentro de ese marco de pila. No puede acceder a ellos desde uno superior o inferior (a menos que haga una aritmética de puntero hacky pero nunca se garantiza que tenga éxito). Desafortunadamente, los grandes bloques de declaraciones de variables son algo con lo que tendrá que convivir.

QuantumPete

perldoc perlguts dice:

   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. No he mirado a Alias.pm lo suficientemente cerca como para ver lo fácil que podría ser.

En TCL puede usar uplevel . En cuanto a Perl, no lo sé.

Perl tiene Sub :: Uplevel

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top