206 Stimmen

Was ist der Unterschied zwischen "my" und "our" in Perl?

Ich weiß, was my ist in Perl. Sie definiert eine Variable, die nur in dem Bereich des Blocks existiert, in dem sie definiert ist. Was bedeutet our tun?

Wie funktioniert our abweichen von my ?

5voto

ismail Punkte 43244

my wird für lokale Variablen verwendet, während our wird für globale Variablen verwendet.

Mehr dazu unter _Variablen-Scoping in Perl: die Grundlagen_ .

5voto

Logan Ding Punkte 1741

Ich bin schon einmal auf einige Fallstricke bei lexikalischen Deklarationen in Perl gestoßen, die mich verwirrt haben und die auch mit dieser Frage zusammenhängen, daher füge ich hier nur meine Zusammenfassung hinzu:

1. Definition oder Erklärung?

local $var = 42;
print "var: $var\n";

Die Ausgabe lautet var: 42 . Wir konnten jedoch nicht feststellen, ob local $var = 42; ist eine Definition oder Erklärung. Aber wie wäre es damit:

use strict;
use warnings;

local $var = 42;
print "var: $var\n";

Das zweite Programm wird einen Fehler auslösen:

Global symbol "$var" requires explicit package name.

$var nicht definiert ist, was bedeutet local $var; ist nur eine Erklärung! Vor der Verwendung local um eine Variable zu deklarieren, stellen Sie sicher, dass sie zuvor als globale Variable definiert wurde.

Aber warum wird das nicht scheitern?

use strict;
use warnings;

local $a = 42;
print "var: $a\n";

Die Ausgabe ist: var: 42 .

Das liegt daran, dass $a sowie $b ist eine globale Variable, die in Perl vordefiniert ist. Erinnern Sie sich an die sortieren Funktion?

2. Lexikalisch oder global?

Ich war C-Programmierer, bevor ich anfing, Perl zu benutzen, daher scheint mir das Konzept der lexikalischen und globalen Variablen einfach zu sein: Es entspricht einfach den 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. Eine automatische Variable hingegen ist eine Variable, die innerhalb eines Funktionsblocks definiert ist. Zum Beispiel so:

int global;

int main(void) {
    int local;
}

In Perl hingegen sind die Dinge subtiler:

sub main {
    $var = 42;
}

&main;

print "var: $var\n";

Die Ausgabe lautet var: 42 . $var ist eine globale Variable, auch wenn sie in einem Funktionsblock definiert ist! Eigentlich ist in Perl jede Variable standardmäßig als global deklariert.

Die Lektion lautet, immer hinzuzufügen use strict; use warnings; am Anfang eines Perl-Programms, was den Programmierer dazu zwingt, die lexikalische Variable explizit zu deklarieren, so dass wir nicht durch einige selbstverständliche Fehler durcheinander gebracht werden.

2voto

Misha Gale Punkte 97

Das hat nur bedingt etwas mit der Frage zu tun, aber ich habe gerade eine (für mich) obskure Perl-Syntax entdeckt, die man mit "our"-Variablen (Paketvariablen) verwenden kann, aber nicht mit "my"-Variablen (lokalen Variablen).

#!/usr/bin/perl

our $foo = "BAR";

print $foo . "\n";
${"foo"} = "BAZ";
print $foo . "\n";

Ausgabe:

BAR
BAZ

Das funktioniert nicht, wenn Sie "unser" in "mein" ändern.

0voto

Lavi Buchnik Punkte 1
print "package is: " . __PACKAGE__ . "\n";
our $test = 1;
print "trying to print global var from main package: $test\n";

package Changed;

{
        my $test = 10;
        my $test1 = 11;
        print "trying to print local vars from a closed block: $test, $test1\n";
}

&Check_global;

sub Check_global {
        print "trying to print global var from a function: $test\n";
}
print "package is: " . __PACKAGE__ . "\n";
print "trying to print global var outside the func and from \"Changed\" package:     $test\n";
print "trying to print local var outside the block $test1\n";

Wird dies ausgeben:

package is: main
trying to print global var from main package: 1
trying to print local vars from a closed block: 10, 11
trying to print global var from a function: 1
package is: Changed
trying to print global var outside the func and from "Changed" package: 1
trying to print local var outside the block 

Bei der Verwendung von "use strict" wird beim Versuch, das Skript auszuführen, dieser Fehler auftreten:

Global symbol "$test1" requires explicit package name at ./check_global.pl line 24.
Execution of ./check_global.pl aborted due to compilation errors.

0voto

Yugdev Punkte 1

Versuchen Sie einfach, das folgende Programm zu verwenden:

#!/usr/local/bin/perl
use feature ':5.10';
#use warnings;
package a;
{
my $b = 100;
our $a = 10;

print "$a \n";
print "$b \n";
}

package b;

#my $b = 200;
#our $a = 20 ;

print "in package b value of  my b $a::b \n";
print "in package b value of our a  $a::a \n";

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X