Wann sollten Sie eine Paketvariable vs einer lexikalischen Variable verwenden (und was ist der Unterschied)?

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

Frage

Ich betrachte einigen älteren Perl-Code auf Perl Monks Programmierung, um herauszufinden, mit Win32 :: OLE und MS Word. Verteilt über den Code sind Variablen mit Namen wie $ MS :: Wort und dergleichen, ohne ein ' mein ' in ihrer Erklärung enthalten. Nach ein bisschen auf Google lesen, verstehe ich, dass diese ‚Paketvariablen‘ versus ‚lexikalische Variablen‘ genannt deklariert mit mein .

Meine erste Frage lautet: ' Was sind Paketvariablen gut? '. Ich (glaube) Ich verstehe, was lexikalische Variablen sind, aber ich verstehe nicht den Zweck der Paketvariablen oder wie ihre Verwendung unterscheidet sich von Lexikale, so meine zweite Frage wäre, ‚ Was ist der Unterschied zwischen lexikalischen und Paketvariablen ?

War es hilfreich?

Lösung

Ein Paket Variable Leben in einer Symboltabelle, seinen Namen so gegeben, es ist möglich, es von einem anderen Paket oder Umfang zu lesen oder zu ändern. Eine lexikalische Variable Anwendungsbereich wird durch den Programmtext bestimmt. Der Abschnitt "Private Variablen über meine ()" die perlsub manpage mehr Details über die Definition Lexikale gibt.

Sagen wir folgende MyModule.pm haben:

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;

Beachten Sie, dass es ein Paket $calls und eine lexikalische $calls enthält. Jeder kann in dem ehemaligen, aber das Modul steuert den Zugriff auf den letzteren:

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

Das Programms der Ausgabe ist

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

Wie Sie sehen können, Paketvariablen sind globale Variablen, so dass alle üblichen gotchas und Abraten anzuwenden. Sofern nicht ausdrücklich Zugang zur Verfügung gestellt, es für Code außerhalb des MyModule Pakets unmöglich ist, seinen lexikalischen $calls zugreifen zu können.

Als Faustregel ist, dass Sie fast immer verwenden Lexikale wollen. Perl Best Practices von Damian Conway direkt ist: „ Nie machen Variablen Teil eines Moduls Schnittstelle “(Hervorhebung im Original).

Andere Tipps

Sie sollten lesen Der Umgang mit Scoping von MJD.

Perldoc perlmod würde auch nützliche Lektüre sein.

Der Code ist nicht von dieser Welt hässlich. Es trampelt auf alle Arten von Namensräumen ohne Sorge in der Welt, nur weil der Autor Autor zu denken $ scheint :: E-Mail cool ist.

Eine bessere Möglichkeit gewesen wäre, einen Hash zu verwenden:

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

überall auf der Symboltabelle Trampeln ist nicht erforderlich.

Ich habe zu tun, ein paar Win32::OLE Beispiele: http://www.unur.com/comp/, die keine Kunstwerke, aber ich glaube, sind Verbesserungen in diesem Stil. Siehe auch Warum die Anzahl der Seiten in einem Word-Dokument unterschiedlich in Perl und Word VBA sind?

Ich werde ein wenig schimpfen :

@pgm::runtime_args = @ARGV ;

So geben wir auf dem Standard @ARGV Array auf dem Spiel pgm Namespace trampeln. Nicht nur das, weiß jeder Perl-Programmierer, was @ARGV ist. In jedem Fall wird @pgm::runtime_args nicht wieder im Skript verwendet.

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

Natürlich @pgm::runtime_args in Skalarkontext würde uns die Anzahl der Elemente in diesem Array. Ich habe keine Ahnung, warum $pgm::maxargs ist erforderlich, aber wenn es wäre, dann sollte diese Linie gewesen sein:

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

Ich werde nicht mehr Zitat von diesem Zeug. Ich denke, das ist, was passiert, wenn Cobol Programmierer versuchen, Perl zu schreiben.

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

Ich bin froh, dass er fünf Stellen für das Jahr verteilt. Ya nie wissen!

PS: Ich glaube, meine Auszüge fair use bilden

.

Packagevariablen sind globale Variablen; sie sind überall sichtbar im gesamten Programm (auch andere Module). Sie sind nützlich, wenn Sie wollen oder müssen, dass Niveau der Sichtbarkeit und / oder äußere Einflüsse. Zum Beispiel des Text :: Wrap-Modul verwendet sie einen einzigen Konfigurationspunkt für die Anzahl der Spalten zu ermöglichen, an dem Text zu wickeln. Futhermore, Paketvariablen erlauben Ihnen etwas „dynamischer Scoping“ genannt zu verwenden - aber das ist ein etwas erweitert und leicht esoterisches Konzept

.

Für Ihre zweite Frage finden Sie unter Was ist der Unterschied zwischen mir und von uns in Perl?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top