Frage

Ich sehe sich beide in diesem Skript verwendete ich zu debuggen versuchen und die Literatur ist einfach nicht klar. Kann jemand das für mich entmystifizieren?

War es hilfreich?

Lösung

Dynamische Scoping. Es ist ein ordentliches Konzept. Viele Menschen sie nicht benutzen, oder sie verstehen.

denkt, im Prinzip aus my wie Erstellen und eine Variable auf einen Block von {}, auch bekannt als Verankerungs Anwendungsbereich.

my $foo if (true); # $foo lives and dies within the if statement.

So ein my Variable ist, was Sie gewohnt sind. während bei dynamisch var Scoping $ kann überall und überall verwendet deklariert werden. Also mit local suspendieren Sie im Grunde die Verwendung dieser globalen Variablen, und verwenden Sie einen „lokalen Wert“ mit ihm zu arbeiten. So local erstellt einen temporären Raum für eine temporäre Variable.

$var = 4;
print $var, "\n";
&hello;
print $var, "\n";

# subroutines
sub hello {
     local $var = 10;
     print $var, "\n";
     &gogo; # calling subroutine gogo
     print $var, "\n";
}
sub gogo {
     $var ++;
}

Dies sollte drucken:

4
10
11
4

Andere Tipps

Die kurze Antwort ist, dass my eine Variable als privat markiert in einem lexikalischen Umfang und local markiert eine Variable als private in einem dynamischen Rahmen.

Es ist einfacher my zu verstehen, denn das ist eine lokale Variable im üblichen Sinne schafft. Es gibt eine neue Variable erstellt und es ist zugänglich nur innerhalb des umschließenden lexikalischen Block, der in der Regel durch geschweifte Klammern gekennzeichnet. Es gibt einige Ausnahmen von der geschweiften Klammer Regel, wie:

foreach my $x (@foo) { print "$x\n"; }

Aber das ist nur Perl zu tun, was Sie meinen. Normalerweise haben Sie so etwas wie folgt aus:

sub Foo {
   my $x = shift;

   print "$x\n";
}

In diesem Fall ist $x privat an das Unterprogramm und dessen Umfang durch die geschweiften Klammern eingeschlossen ist. Die Sache zu beachten, und das ist der Unterschied local, ist, dass der Umfang eines my Variable in Bezug auf Ihren Code definiert ist, wie es in der Datei geschrieben wird. Es ist ein Kompilierung-Phänomen.

Um zu verstehen, local, müssen Sie in Bezug auf den Aufruf-Stack des Programms denken, wie es läuft. Wenn eine Variable local ist, wird sie von dem Punkt neu definiert, bei der die local Aussage für alles auf dem Stapel unter dem ausgeführt wird, bis Sie an den Aufrufer des Blockes auf den Stapel wieder zurück die local enthält.

Dies kann zunächst verwirrend sein, so betrachten Sie das folgende Beispiel.

sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }

$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect

Wenn foo das erste Mal aufgerufen wird, sieht es den globalen Wert von $x die 1. ist Wenn bar genannt wird und local $x Läufe, die die globale $x auf den Stapel neu definiert. Nun, wenn foo von bar genannt wird, sieht er den neuen Wert von 2 für $x. Bisher ist das nicht etwas ganz Besonderes, weil die gleiche Sache, ohne den Anruf geschehen wäre, local. Die Magie ist, dass, wenn Rückkehr bar wir den dynamischen Umfang von local $x erstellt verlassen und der früheren globalen $x kommt zurück in Umfang. Also für den letzten Aufruf von foo, $x 1 ist.

Sie werden fast immer wollen my verwenden, da, dass Sie die lokale Variable gibt, die Sie suchen. Einmal in einem blauen Mond, ist local wirklich praktisch coole Dinge zu tun.

Zitiert von Learning Perl :

  

Aber Lokal ist falsch benannt oder zumindest irreführend genannt. Unser Freund Chip sagt, dass Salzenberg, wenn er jemals eine Chance bekommt bis 1986 in einer Zeitmaschine zurück und gibt Larry einen Rat, er Larry lokale nannte mit Namen sagen würde „retten“ statt. [14] Das ist, weil lokale tatsächlich die gegebenen globalen Variablenwert weg zu speichern, so wird es später automatisch auf die globale Variable wiederhergestellt werden. (Das ist richtig: diese so genannten „lokalen“ Variablen sind eigentlich Globals!) Diese speichern und Wiederherstellungsmechanismus das gleiche ist haben wir schon jetzt zweimal gesehen, in der Regelgröße von einer foreach-Schleife, und in der @_ Array von Subroutine-Parameter.

So spart local eine globale aktuellen Wert der Variablen und es dann zu einer Form von leeren Wert gesetzt. Sie werden oft sehen, es verwendet, um eine ganze Datei schlürfen, eher als führende nur eine Zeile:

my $file_content;
{
    local $/;
    open IN, "foo.txt";
    $file_content = <IN>;
} 

local $/ Aufruf setzt den Eingang voneinander zu trennen ist (den Wert, den Perl hält eine „Linie“ zu lesen) auf einen leeren Wert, wodurch das Raumschiff Betreiber die gesamte Datei zu lesen, so trifft es nie den Eingang voneinander zu trennen ist.

Ich kann nicht glauben, dass niemand zu Mark Jason Dominus’ erschöpfende Abhandlungen über die Angelegenheit verknüpft ist:

http://perldoc.perl.org/perlsub .html # Privat-Variablen-via-my ()

  

Im Gegensatz zu dynamischen Variablen erstellt von   der lokale Betreiber, lexikalische Variablen   erklärt mit meinem völlig versteckt sind   von der Außenwelt, einschließlich aller   genannt Subroutinen. Dies gilt, wenn   es ist das gleiche Unterprogramm aufgerufen aus   selbst oder anderswo - jeder Anruf bekommt   seine eigene Kopie.

http://perldoc.perl.org/perlsub .html # Temporäre-Werte-via-local ()

  

Eine lokale modifiziert seine aufgelisteten Variablen   „Local“ zum umschließenden Block zu sein,   eval oder tun, Datei --Und irgendeinem   Subroutine aus, dass aufgerufen   Block. Ein lokales gibt nur vorübergehend   Werte global (dh Paket)   Variablen. Es schafft nicht eine lokale   Variable. Dies wird als dynamische bekannt   Scoping. Lexikalischen Scoping erfolgt mit   meine, das funktioniert eher wie C des Auto   Erklärungen.

Ich glaube nicht, dass dies überhaupt nicht klar ist, als andere zu sagen, dass durch „lokal auf den umschließenden Block“, was es bedeutet, dass der ursprüngliche Wert gestellt wird, wenn der Block verlassen wird.

Nun Google wirklich funktioniert für Sie auf diesen einen: http://www.perlmonks.org/? node_id = 94007

Aus dem Link:

  

Kurze Zusammenfassung: ‚mein‘ erstellt einen neuen   Variable, ‚lokal‘ vorübergehend ändert   der Wert einer Variablen.

     

dh 'local' vorübergehend ändert sich die   Wert der Variablen , aber nur    im Rahmen es existiert in.

Im Allgemeinen verwenden meint, es schneller ist und tut nichts irgendwie komisch.

Von man perlsub:

Im Gegensatz zu dynamischen Variablen durch den lokalen Betreiber erstellt wurden, lexikalische Variablen deklariert mit meinem sind völlig von der Außenwelt verborgen, alle aufgerufenen Unterprogramme.

Also, vereinfachend, my Ihre Variable sichtbar macht nur dort, wo es erklärt. local macht es auch den Call-Stack sichtbar nach unten. Sie werden in der Regel my verwenden, anstatt local wollen.

Ihre Verwirrung ist verständlich. Lexikalischen Scoping ist ziemlich einfach zu verstehen, aber dynamischer Scoping ist ein ungewöhnliches Konzept. Die Situation wird noch verschlimmert durch die Namen my und local etwas ungenau zu sein (oder zumindest nicht intuitiv) aus historischen Gründen.

my deklariert eine lexikalische Variable - eine, die von dem Punkt der Erklärung bis zum Ende des umschließenden Blockes (oder eine Datei) sichtbar ist. Es ist völlig unabhängig von anderen Variablen mit dem gleichen Namen in dem Rest des Programms. Es ist privat zu diesem Block.

local, auf der anderen Seite, erklärt eine vorübergehende Änderung auf den Wert einer globalen Variablen. Die Änderung endet am Ende des umschließenden Umfangs, aber die Variable - global sein -. Sichtbar ist überall im Programm

Als Faustregel verwendet my eigene Variablen und local zu erklären, die Auswirkungen von Änderungen in dem Perl eingebauter Variablen zu steuern.

siehe

Für eine gründlichere Beschreibung Mark Jason Dominus' Artikel Umgang mit Scoping.

Lokal ist ein älteres Verfahren zur Lokalisierung, von den Zeiten, in denen Perl nur dynamischen Scoping hatten. Lexikalischen Scoping ist viel natürlicher für den Programmierer und viel sicherer in vielen Situationen. meine Variablen gehören zum Umfang (Block, Paket oder Datei), in dem sie deklariert sind.

lokale Variablen anstatt tatsächlich zu einem globalen Namensraum gehören. Wenn Sie auf eine Variable $ x mit lokalen beziehen, werden Sie beziehen tatsächlich auf $ main :: x, die eine globale Variable ist. Im Gegensatz zu dem, was es ist Name schon sagt, alle lokalen tut, ist ein neuer Wert auf einen Stapel von Werten für $ main :: x bis zum Ende dieses Blocks drücken, bei der alte Wert welcher Zeit wiederhergestellt wird. Das ist eine nützliche Funktion an und für sich, aber es ist kein guter Weg, lokale Variablen für eine Vielzahl von Gründen zu haben (man denke, was passiert, wenn Sie Threads haben! Und denken, was passiert, wenn Sie eine Routine aufrufen, die wirklich eine globale nutzen will, dass Sie lokalisiert haben!). Es war jedoch die einzige Möglichkeit, Variablen haben, wie lokal Variablen zurück in den schlechten alten Tagen vor Perl sah 5. Wir mit ihm noch nicht weiterkommen.

„my“ Variablen in dem aktuellen Codeblock ist nur sichtbar. „Lokale“ Variablen sind ebenfalls sichtbar, wo immer sie vor sichtbar waren. Wenn Sie zum Beispiel sagen: „my $ x;“ und rufen Sie eine Unterfunktion, kann es nicht, dass die Variable $ x sehen. Aber wenn Sie sagen, „local $ /;“ (Auf null den Wert des Datensatztrenn out) Sie dann den Weg von Dateien in beliebigen Funktionen arbeitet rufen Sie lesen ändern.

In der Praxis möchte man fast immer "mein", nicht "local".

Lesen Sie den folgenden Code und dessen Ausgang den Unterschied zu verstehen.

our $name = "Abhishek";

sub sub1
{
    print "\nName = $name\n";
    local $name = "Abhijeet";

    &sub2;
    &sub3;
}

sub sub2
{
    print "\nName = $name\n";
}

sub sub3
{
    my $name = "Abhinav";
    print "\nName = $name\n";
}


&sub1;

Die Ausgabe ist:

Name = Abhishek

Name = Abhijeet

Name = Abhinav

dinomite das Beispiel der Verwendung von lokalen das Satzbegrenzer neu zu definieren, ist das einzige Mal, dass ich in einer Menge von Perl-Programmierung über ran. Ich lebe in einer Nische Perl-Umgebung [Sicherheit Programmierung], aber es ist wirklich ein selten verwendet Umfang in meiner Erfahrung.

&s;

sub s()
{
    local $s="5";
    &b;
    print $s;
}

sub b()
{
    $s++;
}

Die obige Skript druckt 6.

Wenn wir aber zu meinem lokalen ändern wird es 5 drucken.

Das ist der Unterschied. Einfach.

Ich denke, der einfachste Weg, es zu erinnern, diese Art und Weise ist. MY erstellt eine neue Variable. LOCAL ändert vorübergehend den Wert einer vorhandenen Variablen.

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