Comment localiser les variables Perl dans un autre cadre de pile?
Question
J'ai un code généré automatiquement qui écrit efficacement les éléments suivants dans un tas d'endroits différents dans un code:
no warnings 'uninitialized';
local %ENV = %ENV;
local $/ = $/;
local @INC = @INC;
local %INC = %INC;
local J'ai un code généré automatiquement qui écrit efficacement les éléments suivants dans un tas d'endroits différents dans un code:
<*>
Lors de la génération automatique de code, certains affirment qu'il n'est pas absolument nécessaire que le code soit "beau", mais j'aimerais le convertir en sous-programme. Cependant, cela localiserait ces variables dans ce sous-programme. Existe-t-il un moyen de localiser ces variables dans le cadre de la pile d’appel?
Mise à jour : dans la même veine, il serait intéressant de pouvoir exécuter eval dans un cadre de pile plus élevé. Je pense que Python a déjà cela. Ce serait bien si Perl le faisait aussi.
= J'ai un code généré automatiquement qui écrit efficacement les éléments suivants dans un tas d'endroits différents dans un code:
<*>
Lors de la génération automatique de code, certains affirment qu'il n'est pas absolument nécessaire que le code soit "beau", mais j'aimerais le convertir en sous-programme. Cependant, cela localiserait ces variables dans ce sous-programme. Existe-t-il un moyen de localiser ces variables dans le cadre de la pile d’appel?
Mise à jour : dans la même veine, il serait intéressant de pouvoir exécuter eval dans un cadre de pile plus élevé. Je pense que Python a déjà cela. Ce serait bien si Perl le faisait aussi.
;
local $| = $|;
local %SIG = %SIG;
use warnings 'uninitialized';
Lors de la génération automatique de code, certains affirment qu'il n'est pas absolument nécessaire que le code soit "beau", mais j'aimerais le convertir en sous-programme. Cependant, cela localiserait ces variables dans ce sous-programme. Existe-t-il un moyen de localiser ces variables dans le cadre de la pile d’appel?
Mise à jour : dans la même veine, il serait intéressant de pouvoir exécuter eval dans un cadre de pile plus élevé. Je pense que Python a déjà cela. Ce serait bien si Perl le faisait aussi.
La solution
Peut-être pourriez-vous organiser le code qui utilise ces sections locales en tant que fermeture? Ensuite, vous pourriez
sub run_with_env {
my ($sub, @args) = @_;
no warnings 'uninitialized';
local %ENV = %ENV;
local $/ = $/;
local @INC = @INC;
local %INC = %INC;
local Peut-être pourriez-vous organiser le code qui utilise ces sections locales en tant que fermeture? Ensuite, vous pourriez
<*> = Peut-être pourriez-vous organiser le code qui utilise ces sections locales en tant que fermeture? Ensuite, vous pourriez
<*>;
local $| = $|;
local %SIG = %SIG;
use warnings 'uninitialized';
$sub->(@args);
}
run_with_env(sub {
# do stuff here
});
run_with_env(sub {
# do different stuff here
});
Autres conseils
Je ne suis pas sûr de savoir pourquoi QuantumPete a été voté, il semble avoir raison sur celui-ci. Vous ne pouvez pas dire à local
d'initialiser des variables dans le bloc appelant. Sa fonctionnalité est particulière et son initialisation / démontage ne fonctionne que sur le bloc où il a été exécuté.
Il existe certains modules expérimentaux tels que Sub :: Uplevel et Devel :: RunBlock qui vous permet de tenter de " imbécile " caller ()
pour les sous-routines ou effectuez un "renvoi en saut en longueur" de valeurs à des cadres de pile supérieurs (respectivement), mais aucune de ces méthodes n'affecte la manière dont local
traite les variables ( J'ai essayé.:)
Donc, pour le moment, il semble bien que vous devrez vivre avec les déclarations locales dans la portée où vous en avez besoin.
Je ne connais pas très bien Perl, alors pardonnez-moi si c'est réellement possible. Mais normalement, les variables locales à un cadre de pile ne sont disponibles que dans ce cadre de pile. Vous ne pouvez pas y accéder depuis un niveau supérieur ou inférieur (à moins que vous ne fassiez des calculs arithmétiques de hacky mais que cela ne soit jamais garanti). Malheureusement, vous devrez vivre avec de gros blocs de déclarations de variables.
QuantumPete
perldoc perlguts dit:
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. Je n'ai pas suffisamment regardé Alias.pm pour voir à quel point cela pourrait être facile.
Dans TCL, vous pouvez utiliser le niveau supérieur . Quant à Perl, je ne sais pas.
Perl a Sub :: Uplevel