2013-06-13 4 views
6

Ragazzi io sono un po 'confuso, stavo giocando con scoping in Perl, quando ho incontrato questo:Differenza tra un blocco e una funzione in termini di 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!" 

ma quando lo faccio this:

{ 
    our $x = "nested"; 
} 

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

Quindi ragazzi potete spiegarmi perché quelli funzionano e no?

risposta

5
  1. di spiegare perché l'esempio del blocco funziona il modo in cui funziona, diamo un'occhiata a our spiegazione da "Modern Perl" book, chapter 5

    il nostro ambito

    Entro determinato campo di applicazione, dichiarare un alias una variabile del pacchetto con il nostro builtin.
    Il nome completo è disponibile ovunque, ma l'alias lessicale è visibile solo all'interno del suo ambito.

    Questo spiega perché le prime due stampe del vostro secondo lavoro esempio (il nostro è ri-dichiarata area di stampa), mentre il terzo non (come la nostra unica alias $ x alla variabile del pacchetto nel campo di applicazione del blocco). Si noti che la stampa $main::x funzionerà correttamente: è solo l'alias che viene applicato al blocco, non la variabile del pacchetto stessa.


  2. Per quanto riguarda la funzione:

    • print our $x; e print our($x) "non funzionano" - vale a dire, correttamente sostengono il valore è inizializzato - dal momento che non hai mai chiamato la funzione che inizializza la variabile. Osservare la differenza:

      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; non funzionerà per lo stesso motivo con il blocco - our Scopes solo l'alias al blocco (cioè in questo caso il corpo del sub) quindi si DEVE o ri- alias nel perimetro del blocco principale (come per esempio print our $x) o usare pacchetto completo globale fuori del sub, nel qual caso si comporterà come previsto:

      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

ma per quanto riguarda lo scopo della funzione? –

+0

@BelmarkCaday - non hai aspettato fino alla seconda modifica :).A proposito, ho omesso i rigidi/avvertimenti nell'ultimo comando semplicemente perché la formattazione di SE ha creato uno scoller orizzontale a causa di una stringa troppo lunga. – DVK

+0

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

6

Per rideterminare la risposta di DVK, our è solo un pratico strumento di aliasing. Ogni variabile che si utilizza in questi esempi è in realtà denominata $main::x. All'interno di qualsiasi ambito lessicale è possibile utilizzare our per creare un alias per tale variabile, con un nome abbreviato, nello stesso ambito; la variabile non si resetta o viene rimossa all'esterno, solo l'alias. Questo è diverso dalla parola chiave my che rende una nuova variabile associata a quell'ambito lessicale.