2013-06-13 12 views
6

Guys Jestem trochę zdezorientowany, grałem z scopingu w Perl, kiedy napotkał tego:Różnica między blokiem i funkcji w zakresie określania zakresu w 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!" 

Ale kiedy robię to:

{ 
    our $x = "nested"; 
} 

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

Więc możecie wyjaśnić mi, dlaczego te działa, a nie?

Odpowiedz

5
  1. Aby wyjaśnić, dlaczego przykład blok działa tak, tak, spójrzmy na our wyjaśnień od "Modern Perl" book, chapter 5

    Nasz zakres

    obrębie danego zakresu oświadczyć alias zmienna pakietu z naszym wbudowanym.
    Pełna nazwa jest dostępna wszędzie, ale alias leksykalny jest widoczny tylko w jej zasięgu.

    To wyjaśnia, dlaczego pierwsze dwa wydruki twojego drugiego przykładu działają (nasz jest ponownie zadeklarowany w zakresie drukowania), podczas gdy trzeci nie zawiera (jako jedynych aliasów $ x do zmiennej pakietu w zakresie bloku). Należy pamiętać, że drukowanie działa poprawnie - to tylko alias, który jest ograniczony do bloku, a nie sama zmienna pakietu.


  2. Jeśli chodzi o funkcję:

    • print our $x; i print our($x) „nie działa” - mianowicie prawidłowo twierdzą wartość jest niezainicjowany - ponieważ nigdy nie nazywa się funkcją zainicjuje zmienną. Zaobserwować różnicę:

      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; nie będzie pracować dla tego samego powodu, z blokiem - our celownicze tylko alias do bloku (czyli w tym przypadku ciała sub) Trzeba więc albo re- alias go w zakresie bloku głównego (jak za print our $x przykład) lub użyj pakietu pełną globalną poza sub, w którym sprawa będzie zachowywać się zgodnie z oczekiwaniami:

      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

, ale co z zakresem funkcji? –

+0

@BmarkmarkCaday - nie czekałeś aż do drugiej edycji :).BTW, pominąłem ścisłe/ostrzeżenia w ostatnim poleceniu po prostu dlatego, że formatowanie SE stworzył poziomy scoller ze względu na zbyt długi ciąg. – DVK

+0

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

6

Aby przywrócić odpowiedź DVK, our jest tylko poręcznym narzędziem aliasingu. Każda zmienna, której używasz w tych przykładach, nazywa się faktycznie $main::x. W dowolnym zakresie leksykalnym można użyć our, aby utworzyć alias do tej zmiennej ze skróconą nazwą w tym samym zakresie; zmienna nie resetuje się lub nie jest usuwana na zewnątrz, tylko alias. Jest to przeciwieństwo słowa kluczowego my, które powoduje, że nowa zmienna jest powiązana z tym zakresem leksykalnym.