Frage

Ich habe einige automatisch generierten Code, der aus den folgenden in einer Reihe von verschiedenen Orten in einigen Code effektiv schreibt:

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

Wenn die automatische Generierung von Code, einige argumentieren, dass es nicht unbedingt erforderlich ist, dass der Code „schön“ sein, aber ich mag, dass in ein Unterprogramm ziehen. Dies würde jedoch diese Variablen in diesem Unterprogramm lokalisieren. Gibt es eine Möglichkeit, diese Variablen im Aufruf Stapelrahmen zu lokalisieren?

Aktualisieren : In ähnlicher Weise wäre es schön sein, um in einem höheren Stapelrahmen eval laufen. Ich denke, Python schon dies hat. Es wäre schön, wenn Perl hat, auch.

War es hilfreich?

Lösung

Vielleicht können Sie für den Code anordnen, die jene Einheimischen verwendet als Verschluss erzeugt werden? Dann könnten Sie

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

Andere Tipps

Nicht sicher, warum QuantumPete downvoted wird, scheint er nach rechts auf dieser zu sein. Sie können nicht local sagen Variablen im Aufrufsatz zu initialisieren. Seine Funktionalität ist etwas Besonderes, und die Initialisierung / Teardown, die es tut funktioniert nur auf dem Block, in dem es ausgeführt wurde.

Es gibt einige experimentelle Module wie Sub :: Uplevel und Devel :: RunBlock die Ihnen erlauben, um zu versuchen, „fool "caller() für Subroutinen oder führen Sie eine‚Weitsprung Rückkehr‘von Werten zu höheren Stapelrahmen (jeweils), aber keiner von ihnen zu tun, etwas zu beeinflussen, wie local behandelt Variablen (ich habe versucht:.)

So jetzt scheint es tatsächlich so aussehen wie Sie mit den lokalen Erklärungen im Rahmen leben müssen, wo sie gebraucht werden.

Ich bin nicht sehr vertraut mit Perl, so verzeiht mir, wenn es tatsächlich möglich ist. Aber normalerweise Variablen lokal zu einem Stapelrahmen sind nur innerhalb dieses Stapelrahmen verfügbar. Sie können nicht darauf zugreifen entweder höher oder niedriger ein (es sei denn, Sie einige Hacky Pointer-Arithmetik zu tun, aber das ist nie garantiert zum Erfolg). Große Blöcke von Variablendeklarationen sind leider etwas müssen Sie leben.

QuantumPete

Perldoc perlguts sagt:

   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. Ich habe nicht an Alias.pm eng genug aussehen, um zu sehen, wie einfach das sein könnte.

In TCL können Sie verwenden uplevel . Wie für Perl, weiß ich nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top