Quand faut-il utiliser une variable de package par rapport à une variable lexicale (et quelle est la différence)?

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

Question

J'examine d'anciens codes Perl sur Perl Monks pour comprendre la programmation. avec Win32 :: OLE et MS Word. Des variables portant des noms tels que $ MS :: Word et similaires sont dispersées dans le code, sans qu'un my ne soit inclus dans leur déclaration. Après avoir lu quelques mots sur Google, je comprends que ce sont les "variables de package" et les "variables lexicales" déclarées à l'aide de mon .

Ma première question est " À quoi servent les variables de package? ". Je (pense) je comprends ce que sont les variables lexicales, mais je ne comprends pas le but des variables de package ou comment leur utilisation diffère de celles du lexical, donc ma deuxième question serait: ' Quelle est la différence entre les variables lexicales et les packages ? '

Était-ce utile?

La solution

Une variable de package réside dans une table de symboles. Par conséquent, étant donné son nom, il est possible de la lire ou de la modifier à partir de tout autre package ou étendue. La portée d'une variable lexicale est déterminée par le texte du programme. La section " Variables privées via my () " dans la page de manuel perlsub donne plus de détails sur la définition des lexicaux.

Disons que nous avons le MyModule.pm suivant:

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;

Notez qu'il contient un paquet $ appels et un $ appels lexical. Tout le monde peut accéder au premier, mais le module contrôle l’accès au second:

#! /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";

La sortie du programme est

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

Comme vous pouvez le constater, les variables de package sont des variables globales. Par conséquent, tous les pièges habituels et les conseils contre s'appliquent. Sauf accès explicitement fourni, il est impossible pour du code situé en dehors du package MyModule d'accéder à son $ call lexical.

En règle générale, vous voulez presque toujours utiliser les lexicaux. Les Meilleures pratiques Perl de Damian Conway sont directs: Jamais intégrer les variables à l'interface d'un module " (italique dans l'original).

Autres conseils

Vous devriez lire Faire face à la portée par MJD.

perldoc perlmod serait également une lecture utile.

Le code est hors de ce monde laid. Il piétine toutes sortes d'espaces de noms sans inquiétude dans le monde simplement parce que l'auteur semble penser que $ author :: email est cool.

Un meilleur moyen aurait été d'utiliser un hachage:

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

Il n'est pas nécessaire de piétiner la table des symboles.

J'ai quelques exemples Win32 :: OLE : http: // www.unur.com/comp/ qui ne sont pas des œuvres d'art mais qui, à mon avis, constituent une amélioration de ce style Voir aussi Pourquoi le nombre de pages d'un document Word est-il différent dans Perl et dans Word VBA?

Je vais me déchaîner un peu :

@pgm::runtime_args = @ARGV ;

Nous abandonnons donc le tableau @ARGV standard pour piétiner l'espace de noms pgm . De plus, chaque programmeur Perl sait ce que @ARGV est. Dans tous les cas, @pgm :: runtime_args n'est plus utilisé dans le script.

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

Bien sûr, @pgm :: runtime_args dans un contexte scalaire nous donnerait le nombre d'éléments dans ce tableau. Je ne sais pas pourquoi $ pgm :: maxargs pourrait être nécessaire, mais si c'était le cas, cette ligne aurait dû être:

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

Je ne vais pas citer plus de ce genre de choses. Je suppose que c’est ce qui se passe lorsque les programmeurs Cobol essaient d’écrire Perl.

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

Je suis heureux qu'il ait attribué cinq chiffres pour l'année. Tu ne sais jamais!

PS: Je crois que mes extraits constituent une utilisation équitable.

Les variables de package sont des variables globales. ils sont visibles partout dans le programme (même dans les autres modules). Ils sont utiles lorsque vous souhaitez ou avez besoin de ce niveau de visibilité et / ou d'influence externe. Par exemple, le module Text :: Wrap les utilise pour autoriser un seul point de configuration pour le nombre de colonnes auxquelles le texte doit être renvoyé. De plus, les variables de package vous permettent d'utiliser quelque chose appelé "dynamique". - mais c'est un concept un peu avancé et légèrement ésotérique.

Pour votre deuxième question, voir quelle est la différence entre mon et notre en Perl?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top