Perl: Verwenden Sie das Modul @list

7

Jemand hat eine Idee, die Array-Variable anstelle des Array- (Listen-) Literals in der use -Funktionsanweisung zu verwenden:

%Vor%

statt

%Vor%

Also schreibt sie z. B.:

%Vor%

das scheinbar wie erwartet funktioniert:

  

2, 10

Dann macht sie es mit einem anderen Modul, z.B. %Code%. Anstelle von

%Vor%
  

0, 1

tut sie:

%Vor%
  

0, 0

Es funktioniert plötzlich nicht mehr, so wie es mit Time::HiRes module funktioniert hat! Etwas Schlimmes passiert hier.

(.. es ist in einer nicht strikten Umgebung. Wenn sie Socket benutzt hätte, hätte sie sogar einen Fehler bekommen. Andererseits bekommt sie in ihrem ersten scheinbar funktionierenden Beispiel überhaupt keinen Hinweis - selbst wenn sie es getan hat use strict dort.)

Jetzt will sie dieses seltsame Verhalten erforschen. Versucht, eine leere Liste zu importieren:

%Vor%
  

2, 10

funktioniert überraschenderweise auch, während es wahrscheinlich nicht so sein sollte:

%Vor%
  

0, 0

Dann gräbt sie ein wenig in diese Module ein und stellt fest, dass der Unterschied zwischen den beiden Modulen darin besteht, dass diese Konstanten nicht jeweils% sind.

Ihre Schlussfolgerung ist, dass die use strict; use warnings; use diagnostics nicht so funktioniert, wie sie erwartet.

Was wäre die beste Erklärung dafür? Was macht sie falsch - Was ist die korrekte Art, ein vordefiniertes Array in der @EXPORT -Anweisung zu verwenden?

    
mykhal 05.12.2013, 09:55
quelle

1 Antwort

19

Dies hat damit zu tun, wenn der Code ausgeführt wird. use wird zur Kompilierzeit ausgeführt, während my @list nur zur Laufzeit ausgeführt wird. Das Array existiert also nicht an dem Punkt, an dem das Modul geladen ist.

Das Modul Socket-Exporte PF_INET und PF_INET6 standardmäßig Es spielt keine Rolle, ob Sie es in die Zeile use setzen. Aber Time :: HiRes exportiert standardmäßig keine Dateien .

Der Fehler, den Sie mit strict bekommen, ist:

  

Bareword "CLOCK_REALTIME" nicht erlaubt, solange "strict subs" in Verwendung ist ...

Das sagt uns, dass Perl nicht weiß, dass CLOCK_REALTIME ein Sub ist, was wahr ist, weil es nicht geladen wurde, wenn wir dies tun:

%Vor%

Was use tut ist require das Modul und import die LIST der Argumente bei der Kompilierung Zeit. Es ist also dasselbe wie:

%Vor%

Wenn wir das wissen, können wir es selbst tun:

%Vor%

So funktioniert es, weil das Array @const im selben Bereich definiert ist und bereits verfügbar ist, wenn der Perl-Interpreter es ausführt.

Da scoping nur ein BEGIN Block vor der Verwendung hinzugefügt wird, funktioniert nicht .

%Vor%

Sie können das Problem umgehen, indem Sie die Variable außerhalb des Blocks BEGIN deklarieren. Auf diese Weise wird es im nächsten BEGIN -Block-Bereich verfügbar sein, und der Wert wird bereits festgelegt, da BEGIN Blöcke werden zur Kompilierzeit in FIFO-Reihenfolge ausgeführt.

%Vor%

Also zur Erinnerung:

  • Das liegt an zwei Dingen: scope und Reihenfolge der Ausführung
  • Die Tatsache, dass Sie ein Array übergeben, ist hier nicht das Problem - das Array wird sein Teil der LISTE , die übergeben wurde
  • Wenn Sie nicht use strict haben, können Sie das Problem nicht einfach finden
  • Wenn Sie einen BEGIN Block vor dem use hinzufügen und die my Deklaration außerhalb von BEGIN platzieren, funktioniert
  • Wenn Sie require anstelle von use und import selbst verwenden, können Sie auch ein Array
  • übergeben
simbabque 05.12.2013, 10:31
quelle

Tags und Links