Was ist der Unterschied zwischen meinem und lokalen in Perl?
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?
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:
-
Und danach, wenn Sie wollen wissen, was
local
für immerhin gut,
Seven Praktische Anwendungen vonlocal
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.
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.