<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<link rel="SHORTCUT ICON" href="../bilder//pl.ico">
<title>Einbinden von Perl-Code </title>
</head>
<body bgcolor="#ffffff">
<hr>
<h1 align="center">Einbinden von Perl-Code</h1>
<table align="center"><tr>
<td><a href="perl_schw.html"> <img src="../bilder//perl_links.gif" alt="[ vorherige Seite ]" width="43" height="30" border="0"></a></td>
<td><a href="../perl-tutorial.html"> <img src="../bilder//perl_titel.gif" alt="[ Titelseite ]" width="81" height="22" border="0"></a></td>
<td><a href="perl_inhalt.html"> <img src="../bilder//perl_inhalt.gif" alt="[ Inhalt ]" width="57" height="22" border="0"></a></td>
<td><a href="perl_index.html"> <img src="../bilder//perl_index.gif" alt="[ Index ]" width="54" height="22" border="0"></a></td>
<td><a href="perl_modul.html"> <img src="../bilder//perl_rechts.gif" alt="[ nächste Seite ]" width="43" height="30" border="0"></a></td>
</tr></table>
<hr>
<ul>
<li><a href="#abs1">Ausführung von externem Code mit
<code>do()</code></a></li>
<li><a href="#abs2">Code-Einbindung mit Hilfe von
<code>require()</code></a></li>
<li><a href="#abs3">Verwendung von <code>use</code></a></li>
</ul>
<a name="abs1"></a><hr>
<h2 align="center">Ausführung von externem Code mit
<code>do()</code></h2>
<hr>
<p>
Wird die Zahl der Subroutinen in einem Programm immer größer
oder verwendet man dieselben (oder ähnliche) Unterprogramme
immer wieder in verschiedenen Programmen, so sollte man den
Programmcode auf mehrere Dateien verteilen. Es empfiehlt sich,
das Hauptprogramm zusammen mit ein paar wichtigen Subroutinen in
einer Datei zu speichern (die dann als Perl-Skript ausgeführt
wird), und alle anderen Subroutinen (bzw. Klassen bei objekt-orientierter
Programmierung) - in logischen Gruppen zusammengefaßt - in
eigenen Dateien abzulegen.
</p>
<p>
Um nun Programmcode aus einer zusätzlichen Datei in ein
Hauptprogramm einzubinden, gibt es in Perl verschiedene
Möglichkeiten.
</p>
<p>
Die einfachste ist die Verwendung der Funktion "<code>do()</code>".
Hiermit wird Programmcode aus einer externen Datei so wie er dort
abgelegt ist in das aktuelle Programm (also an die Stelle, wo
<code>do</code> steht) eingebaut und ausgeführt (so als würde
man <code>eval()</code> auf den Dateiinhalt anwenden).
</p>
<p>
Datei <b><tt>prog.pl</tt></b>:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>#!/usr/local/bin/perl -w<br><br>use strict;<br><br>print "Erste Zeile des Hauptprogramms\n";<br><font color="#0000cc">do "funkt.pl"</font>;<br>print "Ende des Hauptprogramms\n";<br></code></td></tr></table>
</td></tr></table>
<p>
Datei <b><tt>funkt.pl</tt></b>:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>print "Ausgabe aus 'funkt.pl'\n";<br></code></td></tr></table>
</td></tr></table>
<table align="center" bgcolor="#66cc66" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ccffcc" border="0" cellpadding="5" width="100%">
<tr><td><code>Erste Zeile des Hauptprogramms<br>Ausgabe aus 'funkt.pl'<br>Ende des Hauptprogramms<br></code></td></tr></table>
</td></tr></table>
<p>
Wie man sieht, erwartet <code>do()</code> als Argument einen Dateinamen.
Diese Datei wird dann in allen Verzeichnissen gesucht, die im
Array <code>@INC</code> aufgelistet sind (siehe auch den Abschnitt
<a href="perl_modul.html#abs4">Standardmodule</a>).
Befindet sich die gesuchte
Datei in einem Verzeichnis, das nicht standardmäßig
zu <code>@INC</code> gehört, so kann der Pfad (vor dem Aufruf von
<code>do()</code>) beispielsweise durch
</p>
<blockquote>
<code>push(@INC,$verzeichnispfad);</code> </blockquote>
<p>
hinzugefügt werden. </p>
<p>
Ein Nachteil von <code>do()</code> 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 mehrfach durchlaufenen Schleife nicht gerade
empfiehlt.
</p>
<p align="right"><a href="perl_perl.html">[Seitenanfang]</a></p>
<a name="abs2"></a><hr>
<h2 align="center">Code-Einbindung mit Hilfe von
<code>require()</code></h2>
<hr>
<p>
Die Funktion <code>require()</code> bindet im Prinzip genauso wie
<code>do()</code> 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 bereits im Speicher befindet und nicht wieder
neu geladen werden muß.
</p>
<p>
Datei <b><tt>prog.pl</tt></b>:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>#!/usr/local/bin/perl -w<br><br>use strict;<br><br>print "Erste Zeile des Hauptprogramms\n";<br><font color="#0000cc">require "funkt.pl"</font>;<br>print "Ende des Hauptprogramms\n";<br></code></td></tr></table>
</td></tr></table>
<p>
Datei <b><tt>funkt.pl</tt></b>:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>print "Ausgabe aus 'funkt.pl'\n";<br></code></td></tr></table>
</td></tr></table>
<table align="center" bgcolor="#66cc66" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ccffcc" border="0" cellpadding="5" width="100%">
<tr><td><code>Erste Zeile des Hauptprogramms<br>Ausgabe aus 'funkt.pl'<br>Ende des Hauptprogramms<br></code></td></tr></table>
</td></tr></table>
<p>
Ebenso wie <code>do()</code> durchsucht auch <code>require()</code>
alle Verzeichnispfade in <code>@INC</code>.
</p>
<p>
Ein wesentlicher Unterschied zu <code>do()</code> besteht aber darin,
daß der Code in der eingebundenen Datei bei der Ausführung
einen "wahren" Wert (<i>true</i>) zurückliefern muß. Im
obigen Beispiel ist dies relativ offensichtlich, da der Aufruf
"<code>print ...</code>" einen wahren Wert ("1")
zurückgibt (auch wenn er meist nie verwendet wird). Um
sicherzugehen, daß externer Code wirklich zum Schluß
<i>wahr</i> liefert, hat es sich eingebürgert, ans Ende der
Datei eine kurze Zeile mit dem Inhalt "<code>1;</code>"
anzuhängen - sie bewirkt die Auswertung von "1", was <i>wahr</i>
entspricht und ist der letzte Aufruf der Datei und somit der
Rückgabewert an <code>require()</code>.
</p>
<p>
Die Datei <b><tt>funkt.pl</tt></b> aus obigem Beispiel sollte also
besser so aussehen:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>print "Ausgabe aus 'funkt.pl'\n";<br><br><font color="#0000cc">1;</font><br></code></td></tr></table>
</td></tr></table>
<p>
Eine zweite Besonderheit von <code>require()</code>, 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 <i>.pm</i> hinzugefügt wird.
Somit sind die Aufrufe im folgenden Beispiel völlig
äquivalent:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>#!/usr/local/bin/perl -w<br><br>use strict;<br><br>my $dateiname = "extern.pm";<br>require $dateiname;<br>require 'extern.pm';<br>require extern; <font color="#006600"># Automatische Ergänzung von .pm</font><br></code></td></tr></table>
</td></tr></table>
<p>
Während die Dateiendung <i>.pl</i> üblicherweise für
Skripten/Programme genutzt wird, verwendet man <i>.pm</i> für
Dateien, die <b>P</b>erl-<b>M</b>odule enthalten.
</p>
<p align="right"><a href="perl_perl.html">[Seitenanfang]</a></p>
<a name="abs3"></a><hr>
<h2 align="center">Verwendung von <code>use</code></h2>
<hr>
<p>
Noch leistungsfähiger als <code>require()</code> ist
<code>use</code>. Von der Funktion her entspricht
ein <code>use</code>-Aufruf dem einen von <code>require()</code>
gefolgt von <code>import()</code>. 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 <i>import</i>ieren,
damit sie dann genauso wie andere Funktionen im Hauptprogramm
aufgerufen werden können.
</p>
<p>
Ein zweiter Unterschied besteht darin, daß <code>use</code>
nicht (wie <code>require()</code>) an der entsprechenden Stelle zur
Laufzeit des Hauptprogramms abgearbeitet wird, sondern schon bei
der Kompilierung des Programms.
</p>
<p>
Datei <b><tt>prog.pl</tt></b>:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>#!/usr/local/bin/perl -w<br><br>use strict;<br><br>print "Erste Zeile des Hauptprogramms\n";<br><font color="#0000cc">use modul</font>; <font color="#006600"># eigentlich "modul.pm"</font><br>print "Ende des Hauptprogramms\n";<br></code></td></tr></table>
</td></tr></table>
<p>
Datei <b><tt>modul.pm</tt></b>:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>print "Ausgabe aus 'modul.pm'\n";<br><br>1;<br></code></td></tr></table>
</td></tr></table>
<table align="center" bgcolor="#66cc66" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ccffcc" border="0" cellpadding="5" width="100%">
<tr><td><code>Ausgabe aus 'modul.pm'<br>Erste Zeile des Hauptprogramms<br>Ende des Hauptprogramms<br></code></td></tr></table>
</td></tr></table>
<p>
An der Reihenfolge der Ausgabe erkennt man schon, daß der Code
der Datei <i>modul.pm</i> schon abgearbeitet wird, bevor das
eigentliche Hauptprogramm beginnt.
</p>
<p>
Eine wichtige Konsequenz davon ist, daß man nun nicht mehr
durch eine Zeile wie
</p>
<blockquote>
<code>push(@INC,$verzeichnispfad);</code> </blockquote>
<p>
vor dem <code>use</code>-Aufruf im Hautprogramm einen zusätzlichen
Suchpfad angeben kann, da <code>use</code> schon abgearbeitet wird,
bevor überhaupt eine Zeile des Hauptprogramms zur Ausführung
kommt. Zur Lösung dieses Problems kann man den entsprechenden
<code>push</code>-Befehl in einen
<code>BEGIN { ... }</code>-Block
einbetten, dessen Inhalt bereits zur Kompilierungszeit aufgerufen wird.
</p>
<p>
Datei <b><tt>prog.pl</tt></b>:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>#!/usr/local/bin/perl -w<br><br>use strict;<br><br><font color="#0000cc">BEGIN {</font><br> my $pfad = 'subdir';<br> push(@INC,$pfad);<br><font color="#0000cc">}</font><br>print "Erste Zeile des Hauptprogramms\n";<br>use modul;<br>print "Ende des Hauptprogramms\n";<br></code></td></tr></table>
</td></tr></table>
<p>
Besser ist aber die Verwendung von <code>use lib</code>,
um einen oder mehrere Pfade zu <code>@INC</code> hinzuzufügen:
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>#!/usr/local/bin/perl -w<br><br>use strict;<br><br><font color="#0000cc">use lib ('subdir');</font><br><br>print "Erste Zeile des Hauptprogramms\n";<br>use modul;<br>print "Ende des Hauptprogramms\n";<br></code></td></tr></table>
</td></tr></table>
<p>
Datei <b><tt>modul.pm</tt></b> im Unterverzeichnis <b><tt>subdir</tt></b> :
</p>
<table align="center" bgcolor="#ffcc99" border="0" cellpadding="2" width="80%"><tr><td>
<table bgcolor="#ffffcc" border="0" cellpadding="10" width="100%">
<tr><td><code>print "Ausgabe aus 'modul.pm'\n";<br><br>1;<br></code></td></tr></table>
</td></tr></table>
<p align="right"><a href="perl_perl.html">[Seitenanfang]</a></p>
<hr>
<table align="center"><tr>
<td><a href="perl_schw.html"> <img src="../bilder//perl_links.gif" alt="[ vorherige Seite ]" width="43" height="30" border="0"></a></td>
<td><a href="../perl-tutorial.html"> <img src="../bilder//perl_titel.gif" alt="[ Titelseite ]" width="81" height="22" border="0"></a></td>
<td><a href="perl_inhalt.html"> <img src="../bilder//perl_inhalt.gif" alt="[ Inhalt ]" width="57" height="22" border="0"></a></td>
<td><a href="perl_index.html"> <img src="../bilder//perl_index.gif" alt="[ Index ]" width="54" height="22" border="0"></a></td>
<td><a href="perl_modul.html"> <img src="../bilder//perl_rechts.gif" alt="[ nächste Seite ]" width="43" height="30" border="0"></a></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td align="left"><i>Autor:
<a href="mailto:Eike.Grote@web.de">Eike Grote</a></i>
</td>
<td align="right"><i>Version: 2.05 (24.1.2012)</i>
</td>
</tr></table>
</body>
</html>