Wie funktioniert die Perl 'verwenden' - syntax arbeiten?
Beispielcode:
m1.pm
my $a;
my $b;
sub init {
$a = shift;
$b = shift;
}
sub printab {
print "a = -$a-\n";
print "b = -$b-\n";
}
1;
m2.pm
my $a;
my $b;
sub init {
$a = shift;
$b = shift;
}
1;
test.pl
use strict;
use warnings;
use m1;
use m2;
init('hello', 'world');
printab();
Run:
$ perl test.pl
a = --
b = --
$
Was passiert, ist, dass die init('hello', 'world')
Anruf zugeordnet ist m2.pm
und initialisiert die Variablen ($a
und $b
) gibt.
Diese Art von Sinn macht, aber was ich nicht verstehe ist, warum diese Werte nicht verfügbar sind, in test.pl
.
-
Ist es etwas grundlegend falsch, dass ich versuche, hier zu tun? Was ist der richtige Weg, um zwei Module mit gleichen namens Subroutinen und Variablen?
-
Wie genau funktioniert ein Perl -
use
Arbeit? Es würde helfen, wenn jemand könnte es dagegen mit C#include
Richtlinie.
- Warum brauche ich das, bitte siehe diese SO-thread.
- Ist das dein vollständiger code? Sie haben, um Ihre Module zu definieren, die eine
import
routine oder Erben vonExporter
. Wenn nicht, sind Sie nicht exportieren, werden die Unterprogramme intest.pl
- ja, das ist alles.
- Ok, siehe meine Antwort, warum es nicht funktioniert.
- Da m1 und m2 sagen, Sie sind die ihrigen, und dass andere Bereiche sollten Ihre Handschuhe aus von Ihnen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zuerst Lesen perldoc perlmod.
Sie nicht deklarieren einen namespace in entweder-Modul, so ist alles in der
main
namespace. Erklärenpackage m1;
imm1.pm
undpackage m2;
imm2.pm
.Zumindest, sollten Sie implementieren eine
import
- Methode (oder die Erben einesExporter
bietet), so dass Programme, die Module verwenden, können entscheiden, was Sie importieren, von wo.Es scheint mir auch, dass Sie erkunden, um die Kanten von OO.
Weiter:
Vermeiden Sie die Verwendung
$a
und$b
als Variablennamen, da es leicht zu verwechseln mit dem Paket-Variablen$a
und$b
verwendetsort
.Nicht verwenden Kleinbuchstaben Modul Namen: Sie sind reserviert für pragmata.
Einer minimalen Implementierung (alles in einer Datei zum testen Bequemlichkeit) sieht wie folgt aus:
use Module;
implizit tutModule->import()
nach dem laden. Wenn das Paket inModule
benannt ist etwas anderes alsModule
, dannModule->import()
suchen das falsche Paket und nicht importiert nichts. Wenn Sie nicht exportieren, dann gibt es keinen Grund (außer Abkommen), warum der name des Pakets und Modul-name müssen identisch sein.In Perl, die
use
Schlüsselwort ist genau äquivalent zu den folgenden:Also, wenn Sie nicht der Definition eines import-routine im code (oder Erben von
Exporter
), dann sind deine Module nicht importieren, alles intest.pl
Als Sinan gefangen, die Sie nicht deklarieren, ein Paket in Ihren Modulen, so sind Sie standardmäßig auf der
main
Paket. In diesem Fall werden alle Unterprogramme sind inmain
, aber die lexikalische Variablen (deklariert mitmy
) sind nur eingeschränkt auf die Datei, in der Sie deklariert wurden.So
m1
definiertsub init
undsub printab
zu denen die lexikale$a
und$b
sind im Umfang enthalten. Aber dann, wenntest.pl
Lastenm2
, dieinit
routine ist überschrieben mit der neuen definition, die nicht geschlossen wird, um die zwei lexikale mehr. So ist es beim schreiben in das Paket Variablen$main::a
und$main::b
statt der lexikale dieprintab
gebunden ist.Wenn Sie Warnungen aktiviert (die solltest du immer beim lernen), Sie hätten davor gewarnt, über die Unterroutine Neudefinition.
Sollten Sie beginnen jedes Ihrer Module mit:
und dann endet jedes Modul mit:
Dies ist, weil, wenn Sie
use/require
einem Modul, zu der es zurückkehren muss einen wahren Wert an das Ende, so dass Perl weiß, dass es richtig geladen wird.printab()
in der Datei definiert istm1.pm
und hat nur Zugriff auf die$a
und$b
Variablen, die im Gültigkeitsbereich dieser Datei. Die Variablen$a
und$b
imm2.pm
sind, eingeschränkt auf die Datei, und Sie sind verschiedenen Variablen als die$a
und$b
imm1.pm
.init()
setzt die Variablen Gültigkeitsbereich inm2.pm
(denn das ist der Letzte Ort, den&init
Funktion definiert wurde), so ist es nicht die Einstellung die gleichen Variablen, dieprintab()
werden Sie versuchen, zu drucken.package Foo
am Anfang jeder Datei in der OP nicht das lexikalische Variablen aus einer Datei sichtbar, in einer anderen Datei.package A; my $var1 = "x"; 1; package B; print $var1;
- wird dieprint $var1
siehe die variable delcared "in" - Paket?my
variable block-Gültigkeitsbereich (wo das Ende der Datei handelt es sich um eine end-of-block), also in deinem Beispiel$var1
sichtbar ist in beiden Paketen. Wenn ich mit mehr als ein Paket in einer Datei, die ich in der Regel setzen Sie den gesamten Paket-Deklaration in einem block:{package ...; ....}
so, dass die lexikale nicht austretenpackage
Erklärung abgeben, wenn Sie das brauchen.