do()
Um nun Programmcode aus einer zusätzlichen Datei in ein Hauptprogramm einzubinden, gibt es in Perl verschiedene Möglichkeiten.
Die einfachste ist die Verwendung der Funktion "do()
".
Hiermit wird Programmcode aus einer externen Datei so wie er dort
abgelegt ist in das aktuelle Programm (also an die Stelle, wo
do
steht) eingebaut und ausgeführt (so als würde
man eval()
auf den Dateiinhalt anwenden).
Datei prog.pl:
#!/usr/local/bin/perl -w print "Erste Zeile des Hauptprogramms\n"; do "funkt.pl"; print "Ende des Hauptprogramms\n"; |
Datei funkt.pl:
print "Ausgabe aus 'funkt.pl'\n"; |
Erste Zeile des Hauptprogramms Ausgabe aus 'funkt.pl' Ende des Hauptprogramms |
Wie man sieht, erwartet do()
als Argument einen Dateinamen.
Diese Datei wird dann in allen Verzeichnissen gesucht, die im
Array @INC
aufgelistet sind. Befindet sich die gesuchte
Datei in einem Verzeichnis, das nicht standardmäßig
zu @INC
gehört, so kann der Pfad (vor dem Aufruf von
do()
) beispielsweise durch
push(@INC,$verzeichnispfad);
hinzugefügt werden.
Ein Nachteil von do()
ist die Tatsache, das jedesmal,
wenn diese Funktion aufgerufen wird, die entsprechende Datei
geöffnet, gelesen und geparst wird, weswegen sich der Einsatz
z.B. innerhalb einer oft durchlaufenen Schleife nicht gerade
empfiehlt.
require()
require()
bindet im Prinzip genauso wie
do()
Programmcode aus einer externen Datei ein, allerdings
mit dem Unterschied, daß das Einlesen nur einmal geschieht und
Perl beim nächsten Aufruf schon "weiß", daß sich
der entsprechende Code schon im Speicher befindet und nicht wieder
neu geladen werden muß.
Datei prog.pl:
#!/usr/local/bin/perl -w print "Erste Zeile des Hauptprogramms\n"; require "funkt.pl"; print "Ende des Hauptprogramms\n"; |
Datei funkt.pl:
print "Ausgabe aus 'funkt.pl'\n"; |
Erste Zeile des Hauptprogramms Ausgabe aus 'funkt.pl' Ende des Hauptprogramms |
Ebenso wie do()
durchsucht auch require()
alle Verzeichnispfade in @INC
.
Ein wesentlicher Unterschied zu do()
besteht aber darin,
daß der Code in der eingebundenen Datei bei der Ausführung
eine "wahren" Wert (true) zurückliefern muß. Im
obigen Beispiel ist dies relativ offensichtlich, da der Aufruf
print ...
"1;
"
anzuhängen - sie bewirkt die Auswertung von "1", was true
entspricht und ist der letzte Aufruf der Datei und somit der
Rückgabewert an require()
.
Die Datei funkt.pl aus obigem Beispiel sollte also besser so aussehen:
print "Ausgabe aus 'funkt.pl'\n"; 1; |
Eine zweite Besonderheit von require()
, die bei
der Verwendung von sogenannten Modulen ausgenutzt wird, ist die
Tatsache, daß falls als Argument ein Name angegeben wird, der
nicht einen in Anführungsstrichen stehenden String darstellt,
an diesen Namen automatisch die Endung .pm hinzugefügt wird.
Somit sind die Aufrufe im folgenden Beispiel völlig
äquivalent:
#!/usr/local/bin/perl -w $dateiname = "extern.pm"; require $dateiname; require 'extern.pm'; require extern; # Automatische Ergänzung von .pm |
Während die Dateiendung .pl üblicherweise für Skripten/Programme genutzt wird, verwendet man .pm für Dateien, die Perl-Module enthalten.
use()
require()
ist die
Funktion use()
. Von der Funktion her entspricht
ein use
-Aufruf dem einen von require
gefolgt von import
. Letztere ist keine von Perl
vordefinierte Funktion sondern eine Funktion, die in einem
einzubindenden Modul definiert wird und üblicherweise
dazu verwendet wird, um Funktionsnamen zu importieren,
damit sie dann genauso wie andere Funktionen im Hauptprogramm
aufgerufen werden können.
Ein zweiter Unterschied besteht darin, daß use()
nicht (wie require()
) an der entsprechenden Stelle zur
Laufzeit des Hauptprogramms abgearbeitet wird, sondern schon bei
der Kompilierung des Programms.
Datei prog.pl:
#!/usr/local/bin/perl -w print "Erste Zeile des Hauptprogramms\n"; use modul; # eigentlich "modul.pm" print "Ende des Hauptprogramms\n"; |
Datei modul.pm:
print "Ausgabe aus 'modul.pm'\n"; 1; |
Ausgabe aus 'modul.pm' Erste Zeile des Hauptprogramms Ende des Hauptprogramms |
An der Reihenfolge der Ausgabe erkennt man schon, daß der Code der Datei modul.pm schon abgearbeitet wird, bevor das eigentliche Hauptprogramm beginnt.
Eine wichtige Konsequenz davon ist, daß man nun nicht mehr durch eine Zeile wie
push(@INC,$verzeichnispfad);
vor dem use
-Aufruf im Hautprogramm einen zusätzlichen
Suchpfad angeben kann, da use()
schon abgearbeitet wird,
bevor überhaupt eine Zeile des Hauptprogramms zur Ausführung
kommt. Zur Lösung dieses Problems kann man den entsprechenden
push
-Befehl in einen
BEGIN { ... }
-BlockDatei prog.pl:
#!/usr/local/bin/perl -w BEGIN { $pfad = 'subdir'; push(@INC,$pfad); } print "Erste Zeile des Hauptprogramms\n"; use modul; print "Ende des Hauptprogramms\n"; |
Datei modul.pm im Unterverzeichnis subdir :
print "Ausgabe aus 'modul.pm'\n"; 1; |
Autor: Eike Grote | Letzte Änderung: 18.02.1999 |