Quando dovresti usare una variabile del pacchetto contro una variabile lessicale (e qual è la differenza)?

StackOverflow https://stackoverflow.com/questions/1019617

Domanda

Sto guardando alcuni vecchi codici Perl su Perl Monks per capire la programmazione con Win32 :: OLE e MS Word. Sparse nel codice sono variabili con nomi come $ MS :: Word e simili, senza un " mio " incluso nella loro dichiarazione. Dopo aver letto un po 'su Google, capisco che queste sono chiamate "variabili del pacchetto" contro "variabili lessicali" dichiarate usando my .

La mia prima domanda è ' A cosa servono le variabili del pacchetto? '. Io (penso) capisco cosa sono le variabili lessicali, ma non capisco lo scopo delle variabili del pacchetto o in che modo il loro uso differisce dai lessici, quindi la mia seconda domanda sarebbe: " Qual è la differenza tra variabili lessicali e pacchetto ? '

È stato utile?

Soluzione

Una variabile di pacchetto risiede in una tabella di simboli, quindi, dato il suo nome, è possibile leggerla o modificarla da qualsiasi altro pacchetto o ambito. L'ambito di una variabile lessicale è determinato dal testo del programma. La sezione " Variabili private tramite my () " nella manpage di perlsub fornisce maggiori dettagli sulla definizione di lessici.

Supponiamo che abbiamo il seguente MyModule.pm :

package MyModule;

# these are package variables
our $Name;
$MyModule::calls = "I do not think it means what you think it means.";

# this is a lexical variable
my $calls = 0;

sub say_hello {
  ++$calls;

  print "Hello, $Name!\n";
}

sub num_greetings {
  $calls;
}

1;

Nota che contiene un pacchetto $ chiamate e un $ chiamate lessicale. Chiunque può accedere al primo, ma il modulo controlla l'accesso al secondo:

#! /usr/bin/perl

use warnings;
use strict;

use MyModule;

foreach my $name (qw/ Larry Curly Moe Shemp /) {
  $MyModule::Name = $name;
  MyModule::say_hello;
}

print MyModule::num_greetings, "\n";

print "calls = $MyModule::calls\n";

L'output del programma è

Hello, Larry!
Hello, Curly!
Hello, Moe!
Hello, Shemp!
4
calls = I do not think it means what you think it means.

Come puoi vedere, le variabili del pacchetto sono globali, quindi valgono tutti i consueti consigli e suggerimenti. A meno che non venga esplicitamente fornito l'accesso, è impossibile per il codice esterno al pacchetto MyModule accedere ai suoi $ chiamate .

La regola empirica è che quasi sempre vuoi usare i lessici. Best Practices Perl di Damian Conway è diretto: " Mai rendere le variabili parte dell'interfaccia di un modulo " (enfasi in originale).

Altri suggerimenti

Dovresti leggere Far fronte allo scoping di MJD.

perldoc perlmod sarebbe anche una lettura utile.

Il codice è brutto da questo mondo. Calpesta tutti i tipi di spazi dei nomi senza preoccuparsi del mondo solo perché l'autore sembra pensare $ author :: email is cool.

Un modo migliore sarebbe stato usare un hash:

my %author = (
   email => 'author@example.com',
   ...
);

Non è necessario calpestare tutta la tabella dei simboli.

Ho alcuni esempi Win32 :: OLE : http: // www.unur.com/comp/ che non sono opere d'arte ma credo siano miglioramenti di questo stile. Vedi anche Perché il numero di pagine in un documento Word è diverso in Perl e Word VBA?

Sto andando a prendere in giro un po ':

@pgm::runtime_args = @ARGV ;

Quindi, rinunciamo alla matrice standard @ARGV per calpestare lo spazio dei nomi pgm . Non solo, ogni programmatore Perl sa cos'è @ARGV . In ogni caso, @pgm :: runtime_args non viene più usato nello script.

$pgm::maxargs = $#pgm::runtime_args + 1 ;

Naturalmente @pgm :: runtime_args in un contesto scalare ci darebbe il numero di elementi in quell'array. Non ho idea del motivo per cui $ pgm :: maxargs potrebbe essere necessario, ma se lo fosse, allora questa riga avrebbe dovuto essere:

$pgm::maxargs = @pgm::runtime_args;

Non ho intenzione di citare più di queste cose. Immagino che sia quello che succede quando i programmatori Cobol provano a scrivere Perl.

$program::copyright = "Copyright (c) 02002 - Kenneth Tomiak : All rights reserved.";

Sono contento che abbia assegnato cinque cifre per l'anno. Non lo sai mai!

PS: credo che i miei estratti costituiscano un uso corretto.

Le variabili del pacchetto sono variabili globali; sono visibili ovunque nell'intero programma (anche altri moduli). Sono utili quando vuoi o hai bisogno di quel livello di visibilità e / o influenza esterna. Ad esempio il modulo Text :: Wrap li utilizza per consentire un singolo punto di configurazione per il numero di colonne in cui avvolgere il testo. Inoltre, le variabili del pacchetto ti consentono di utilizzare qualcosa chiamato "scoping dinamico" - ma è un concetto un po 'avanzato e leggermente esoterico.

Per la tua seconda domanda, vedi Qual è la differenza tra il mio e il nostro in Perl?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top