Ich weiß, was my
in Perl ist. Es definiert eine Variable, die nur im Bereich des Blocks existiert, in dem sie definiert ist. Was macht our
das
Wie unterscheidet our
sich von my
?
Gute Frage: Wie unterscheidet our
sich von my
und was macht our
?
Zusammenfassend:
Verfügbar seit Perl 5 my
ist eine Möglichkeit, Nicht-Paket-Variablen zu deklarieren:
$package_name::variable
.Andererseits sind our
Variablen Paketvariablen und somit automatisch:
$package_name::variable
.Wenn Sie eine Variable mit our
deklarieren, können Sie Variablen vorab deklarieren, um sie unter zu verwenden, use strict
ohne Tippfehler oder Fehler bei der Kompilierung zu erhalten. Seit Perl 5.6 hat es das veraltete ersetzt use vars
, das nur einen Dateibereich und keinen lexikalischen Gültigkeitsbereich hatte our
.
Zum Beispiel ist der formale, qualifizierte Name für Variable $x
innen package main
ist $main::x
. Durch das Deklarieren our $x
können Sie die nackte $x
Variable im Rahmen der Deklaration ohne Strafe (dh ohne daraus resultierenden Fehler) verwenden, wenn das Skript use strict
oder verwendet use strict "vars"
. Der Gültigkeitsbereich kann ein oder zwei oder mehr Pakete oder ein kleiner Block sein.
local
keine Variablen. Es bezieht sich überhaupt nicht aufmy
undour
.local
Sichert vorübergehend den Wert der Variablen und löscht ihren aktuellen Wert.our
Variablen sind keine Paketvariablen. Sie haben keinen globalen Gültigkeitsbereich, sondern Variablen mit lexikalischem Gültigkeitsbereich, genau wiemy
Variablen. Sie können das im folgenden Programm sehen :package Foo; our $x = 123; package Bar; say $x;
. Wenn Sie eine Paketvariable "deklarieren" möchten, müssen Sie verwendenuse vars qw( $x );
.our $x;
deklariert eine Variable mit lexikalischem Gültigkeitsbereich, die auf die gleichnamige Variable in dem Paket ausgerichtet ist, in dem dieour
kompiliert wurde.Die PerlMonks- und PerlDoc-Links von Cartman und Olafur sind eine großartige Referenz - unten ist mein Riss bei einer Zusammenfassung:
my
Variablen werden lexikalisch in einem einzelnen Block definiert, der durch{}
oder in derselben Datei definiert ist, wenn nicht in{}
s. Auf sie kann nicht über Pakete / Unterprogramme zugegriffen werden, die außerhalb desselben lexikalischen Bereichs / Blocks definiert sind.our
Variablen sind in einem Paket / einer Datei enthalten und können von jedem Code aus aufgerufen werden, deruse
oderrequire
diese Paket- / Dateinamenkonflikte zwischen Paketen gelöst werden, indem der entsprechende Namespace vorangestellt wird.Nur um es abzurunden,
local
Variablen „dynamisch“ scoped, die sich vonmy
Variablen, dass sie von Subroutinen auch zugänglich sind aus dem gleichen Block genannt.quelle
my
Variablen haben einen lexikalischen [...] Gültigkeitsbereich innerhalb derselben Datei, wenn nicht in{}
s". Das war nützlich für mich, danke.Ein Beispiel:
quelle
Der Umgang mit Scoping bietet einen guten Überblick über die Perl-Scoping-Regeln. Es ist alt genug, dass
our
es im Text nicht behandelt wird. Es wird im Abschnitt Notizen am Ende behandelt.Der Artikel befasst sich mit Paketvariablen und dem dynamischen Bereich und wie sich dieser von lexikalischen Variablen und dem lexikalischen Bereich unterscheidet.
quelle
my
wird für lokale Variablen verwendet, währendour
es für globale Variablen verwendet wird.Weitere Informationen finden Sie unter Variable Scoping in Perl: die Grundlagen .
quelle
${^Potato}
ist global. Es bezieht sich auf dieselbe Variable, unabhängig davon, wo Sie sie verwenden.Ich bin jemals auf einige Fallstricke bei lexikalischen Erklärungen in Perl gestoßen, die mich durcheinander gebracht haben und die auch mit dieser Frage zusammenhängen. Deshalb füge ich hier einfach meine Zusammenfassung hinzu:
1. Definition oder Erklärung?
Die Ausgabe ist
var: 42
. Wir konnten jedoch nicht sagen, oblocal $var = 42;
es sich um eine Definition oder Deklaration handelt. Aber wie wäre es damit:Das zweite Programm gibt einen Fehler aus:
$var
ist nicht definiert, was bedeutet,local $var;
ist nur eine Erklärung! Stellen Sie vorlocal
dem Deklarieren einer Variablen sicher, dass sie zuvor als globale Variable definiert wurde.Aber warum scheitert das nicht?
Die Ausgabe ist :
var: 42
.Dies liegt daran
$a
, dass$b
in Perl eine globale Variable vordefiniert ist. Erinnerst du dich an die Sortierfunktion ?2. Lexikalisch oder global?
Ich war ein C-Programmierer, bevor ich anfing, Perl zu verwenden, daher scheint mir das Konzept der lexikalischen und globalen Variablen einfach zu sein: Es entspricht nur automatischen und externen Variablen in C. Aber es gibt kleine Unterschiede:
In C ist eine externe Variable eine Variable, die außerhalb eines Funktionsblocks definiert ist. Andererseits ist eine automatische Variable eine Variable, die innerhalb eines Funktionsblocks definiert ist. So was:
In Perl sind die Dinge subtil:
Die Ausgabe ist
var: 42
.$var
ist eine globale Variable, auch wenn sie in einem Funktionsblock definiert ist! Tatsächlich wird in Perl jede Variable standardmäßig als global deklariert.Die Lektion besteht darin, immer
use strict; use warnings;
am Anfang eines Perl-Programms hinzuzufügen , wodurch der Programmierer gezwungen wird, die lexikalische Variable explizit zu deklarieren, damit wir nicht durch einige Fehler durcheinander geraten, die für selbstverständlich gehalten werden.quelle
Der Perldoc hat eine gute Definition unserer.
quelle
Dies hängt nur ein wenig mit der Frage zusammen, aber ich habe gerade ein (für mich) obskures Stück Perl-Syntax entdeckt, das Sie mit "unseren" (Paket-) Variablen verwenden können, das Sie mit "my" (lokal) nicht verwenden können. Variablen.
Ausgabe:
Dies funktioniert nicht, wenn Sie "unser" in "mein" ändern.
quelle
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
Ausgabe:barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
Ausgabe:barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
Ausgabe:barbar
Bei meinen Tests war ich also in dieselbe Falle geraten. $ {foo} ist dasselbe wie $ foo, die Klammern sind beim Interpolieren hilfreich. $ {"foo"} ist eigentlich ein Blick nach $ main :: {}, der Hauptsymboltabelle, da diese nur Variablen mit Paketbereich enthält.perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
, da in diesem Zusammenhang $ {"foo"} jetzt gleich $ {"test :: foo"} ist. Of Symbol Tables and Globs enthält einige Informationen, ebenso wie das Advanced Perl-Programmierbuch. Entschuldigung für meinen vorherigen Fehler.Wird dies ausgeben:
Wenn bei Verwendung von "use strict" beim Versuch, das Skript auszuführen, der folgende Fehler auftritt:
quelle
Versuchen Sie einfach, das folgende Programm zu verwenden:
quelle
quelle
our
undmy
anders? Wie zeigt dieses Beispiel es?Lassen Sie uns überlegen, was ein Interpreter eigentlich ist: Es ist ein Code, der Werte im Speicher speichert und die Anweisungen in einem Programm, das er interpretiert, auf diese Werte anhand ihrer Namen zugreifen lässt, die in diesen Anweisungen angegeben sind. Die große Aufgabe eines Interpreters besteht also darin, die Regeln zu bestimmen, wie die Namen in diesen Anweisungen verwendet werden sollen, um auf die vom Interpreter gespeicherten Werte zuzugreifen.
Bei der Begegnung mit "my" erstellt der Interpreter eine lexikalische Variable: einen benannten Wert, auf den der Interpreter nur zugreifen kann, während er einen Block ausführt, und nur innerhalb dieses syntaktischen Blocks. Bei der Begegnung mit "our" erstellt der Interpreter einen lexikalischen Alias einer Paketvariablen: Er bindet einen Namen, den der Interpreter fortan als Namen einer lexikalischen Variablen verarbeiten soll, bis der Block fertig ist, an den Wert des Pakets Variable mit dem gleichen Namen.
Der Effekt ist, dass Sie dann so tun können, als würden Sie eine lexikalische Variable verwenden, und die Regeln für die strikte Qualifizierung von Paketvariablen umgehen können. Da der Interpreter bei der ersten Verwendung automatisch Paketvariablen erstellt, kann der Nebeneffekt der Verwendung von "our" auch darin bestehen, dass der Interpreter auch eine Paketvariable erstellt. In diesem Fall werden zwei Dinge erstellt: eine Paketvariable, auf die der Interpreter von überall aus zugreifen kann, vorausgesetzt, sie wird ordnungsgemäß als durch 'use strict' (vorangestellt mit dem Namen des Pakets und zwei Doppelpunkten) bezeichnet, und ihr lexikalischer Alias.
Quellen:
quelle