2013-06-13 5 views
6

Jungen, die ich ein wenig verwirrt bin, war ich mit Scoping in Perl zu spielen, wenn ich begegne diesen:Unterschied zwischen einem Block und einer Funktion in Bezug auf dem Scoping in Perl

#! usr/bin/perl 
use warnings; 
use strict; 

sub nested { 
    our $x = "nested!"; 
} 

print $x;  # Error "Variable "$x" is not imported at nested line 10." 
print our $x; # Doesn't print "nested!" 
print our($x) # Doesn't print "nested!" 

Aber wenn ich tue dies:

{ 
    our $x = "nested"; 
} 

print our($x); # Prints "nested" 
print our $x; # Prints "nested" 
print $x;  # Prints "nested" 

So Jungs können Sie mir erklären, warum diese funktioniert und nicht?

Antwort

5
  1. Um zu erklären, warum der Block Beispiel, wie es funktioniert, lassen Sie uns bei our Erklärung von "Modern Perl" book, chapter 5

    Unsere Scope

    Im gegebenen Rahmen erklären einen Aliasnamen suchen funktioniert auf eine Paketvariable mit unserem eingebauten.
    Der vollqualifizierte Name ist überall verfügbar, aber der lexikalische Alias ​​ist nur innerhalb seines Gültigkeitsbereichs sichtbar.

    Dies erklärt, warum die ersten beiden Abzüge Ihrer zweiten Beispiel der Arbeit (unsere ist in gedruckter Form des Oszilloskops erneut erklärt), während der dritte nicht (wie unsere einzige Aliase $ x auf die Paketvariablen in den Anwendungsbereich der Block). Bitte beachten Sie, dass der Druck $main::x korrekt funktioniert - es ist nur der Alias, der auf den Block beschränkt ist, nicht die Paketvariable selbst.


  2. Soweit mit der Funktion:

    • print our $x; und print our($x) „nicht funktionieren“ - nämlich richtig behaupten, der Wert ist nicht initialisierten - da man nie die Funktion aufgerufen, würde die Variable initialisieren. Beachten Sie den Unterschied:

      c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} print our $x" 
      Use of uninitialized value $x in print at -e line 1. 
      
      c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} x(); print our $x" 
      1 
      
    • print $x; nicht aus dem gleichen Grund wie bei dem Block arbeiten - our nur Tive den Alias ​​auf den Block (dh in diesem Fall Körper des Unter) Sie müssen daher entweder re- alias es in dem Anwendungsbereich des Hauptblockes (gemäß print our $x Beispiel), oder der vollständigen Paket global außerhalb des Unter verwenden, wobei in diesem Fall verhalten sich wie erwartet:

      c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} print $main::x" 
      Use of uninitialized value $x in print at -e line 1. 
      
      c:\>perl -e "sub x { our $x = 1;} x(); print $main::x" 
      1 
      
+0

aber was ist mit dem Funktionsumfang? –

+0

@BelmarkCaday - Sie haben nicht bis zur zweiten Bearbeitung gewartet :).Übrigens habe ich strict/warnings im letzten Befehl einfach weggelassen, weil die SE-Formatierung den horizontalen Scoller wegen der zu langen Zeichenfolge erstellt hat. – DVK

+0

@DVK: '$ perl -Mstrict -we '...'' – Zaid

6

Um die Antwort von DVK zu wiederholen, ist our nur ein praktisches Aliasing-Tool. Jede Variable, die Sie in diesen Beispielen verwenden, heißt eigentlich $main::x. Innerhalb eines lexikalischen Bereichs können Sie our verwenden, um einen Alias ​​für diese Variable mit einem verkürzten Namen in demselben Bereich zu erstellen. Die Variable wird nicht zurückgesetzt oder entfernt, sondern nur der Alias. Dies ist anders als das Schlüsselwort my, das eine neue Variable an diesen lexikalischen Gültigkeitsbereich bindet.

Verwandte Themen