The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
<!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&auml;chste Seite ]" width="43" height="30" border="0"></a></td>
  </tr></table>
  <hr>

  <ul>
<li><a href="#abs1">Ausf&uuml;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&uuml;hrung von externem Code mit
<code>do()</code></h2>
  <hr>
  <p>

Wird die Zahl der Subroutinen in einem Programm immer gr&ouml;&szlig;er
oder verwendet man dieselben (oder &auml;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&uuml;hrt
wird), und alle anderen Subroutinen (bzw. Klassen bei objekt-orientierter
Programmierung) - in logischen Gruppen zusammengefa&szlig;t - in
eigenen Dateien abzulegen.
  </p>
  <p>

Um nun Programmcode aus einer zus&auml;tzlichen Datei in ein
Hauptprogramm einzubinden, gibt es in Perl verschiedene
M&ouml;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&uuml;hrt (so als w&uuml;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&nbsp;-w<br><br>use&nbsp;strict;<br><br>print&nbsp;"Erste&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms\n";<br><font color="#0000cc">do&nbsp;"funkt.pl"</font>;<br>print&nbsp;"Ende&nbsp;des&nbsp;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&nbsp;"Ausgabe&nbsp;aus&nbsp;'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&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms<br>Ausgabe&nbsp;aus&nbsp;'funkt.pl'<br>Ende&nbsp;des&nbsp;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&auml;&szlig;ig
zu <code>@INC</code> geh&ouml;rt, so kann der Pfad (vor dem Aufruf von
<code>do()</code>) beispielsweise durch
  </p>
  <blockquote>
<code>push(@INC,$verzeichnispfad);</code>  </blockquote>
  <p>
hinzugef&uuml;gt werden.  </p>
  <p>

Ein Nachteil von <code>do()</code> ist die Tatsache, das jedesmal,
wenn diese Funktion aufgerufen wird, die entsprechende Datei
ge&ouml;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&szlig; das Einlesen nur einmal geschieht und 
Perl beim n&auml;chsten Aufruf schon "wei&szlig;", da&szlig; sich
der entsprechende Code bereits im Speicher befindet und nicht wieder
neu geladen werden mu&szlig;.
  </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&nbsp;-w<br><br>use&nbsp;strict;<br><br>print&nbsp;"Erste&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms\n";<br><font color="#0000cc">require&nbsp;"funkt.pl"</font>;<br>print&nbsp;"Ende&nbsp;des&nbsp;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&nbsp;"Ausgabe&nbsp;aus&nbsp;'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&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms<br>Ausgabe&nbsp;aus&nbsp;'funkt.pl'<br>Ende&nbsp;des&nbsp;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&szlig; der Code in der eingebundenen Datei bei der Ausf&uuml;hrung
einen "wahren" Wert (<i>true</i>) zur&uuml;ckliefern mu&szlig;. Im
obigen Beispiel ist dies relativ offensichtlich, da der Aufruf
"<code>print&nbsp;...</code>" einen wahren Wert ("1")
zur&uuml;ckgibt (auch wenn er meist nie verwendet wird). Um
sicherzugehen, da&szlig; externer Code wirklich zum Schlu&szlig;
<i>wahr</i> liefert, hat es sich eingeb&uuml;rgert, ans Ende der
Datei eine kurze Zeile mit dem Inhalt "<code>1;</code>"
anzuh&auml;ngen - sie bewirkt die Auswertung von "1", was <i>wahr</i>
entspricht und ist der letzte Aufruf der Datei und somit der 
R&uuml;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&nbsp;"Ausgabe&nbsp;aus&nbsp;'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&szlig; falls als Argument ein Name angegeben wird, der
nicht einen in Anf&uuml;hrungsstrichen stehenden String darstellt,
an diesen Namen automatisch die Endung <i>.pm</i> hinzugef&uuml;gt wird.
Somit sind die Aufrufe im folgenden Beispiel v&ouml;llig
&auml;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&nbsp;-w<br><br>use&nbsp;strict;<br><br>my&nbsp;$dateiname&nbsp;=&nbsp;"extern.pm";<br>require&nbsp;$dateiname;<br>require&nbsp;'extern.pm';<br>require&nbsp;extern;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#006600">#&nbsp;Automatische&nbsp;Erg&auml;nzung&nbsp;von&nbsp;.pm</font><br></code></td></tr></table>
</td></tr></table>
  <p>

W&auml;hrend die Dateiendung <i>.pl</i> &uuml;blicherweise f&uuml;r
Skripten/Programme genutzt wird, verwendet man <i>.pm</i> f&uuml;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&auml;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 &uuml;blicherweise
dazu verwendet wird, um Funktionsnamen zu <i>import</i>ieren,
damit sie dann genauso wie andere Funktionen im Hauptprogramm
aufgerufen werden k&ouml;nnen.
  </p>
  <p>

Ein zweiter Unterschied besteht darin, da&szlig; <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&nbsp;-w<br><br>use&nbsp;strict;<br><br>print&nbsp;"Erste&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms\n";<br><font color="#0000cc">use&nbsp;modul</font>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#006600">#&nbsp;eigentlich&nbsp;"modul.pm"</font><br>print&nbsp;"Ende&nbsp;des&nbsp;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&nbsp;"Ausgabe&nbsp;aus&nbsp;'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&nbsp;aus&nbsp;'modul.pm'<br>Erste&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms<br>Ende&nbsp;des&nbsp;Hauptprogramms<br></code></td></tr></table>
</td></tr></table>
  <p>

An der Reihenfolge der Ausgabe erkennt man schon, da&szlig; der Code
der Datei <i>modul.pm</i> schon abgearbeitet wird, bevor das
eigentliche Hauptprogramm beginnt.
  </p>
  <p>

Eine wichtige Konsequenz davon ist, da&szlig; 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&auml;tzlichen
Suchpfad angeben kann, da <code>use</code> schon abgearbeitet wird,
bevor &uuml;berhaupt eine Zeile des Hauptprogramms zur Ausf&uuml;hrung
kommt. Zur L&ouml;sung dieses Problems kann man den entsprechenden
<code>push</code>-Befehl in einen
<code>BEGIN&nbsp;{&nbsp;...&nbsp;}</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&nbsp;-w<br><br>use&nbsp;strict;<br><br><font color="#0000cc">BEGIN&nbsp;{</font><br>&nbsp;&nbsp;my&nbsp;$pfad&nbsp;=&nbsp;'subdir';<br>&nbsp;&nbsp;push(@INC,$pfad);<br><font color="#0000cc">}</font><br>print&nbsp;"Erste&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms\n";<br>use&nbsp;modul;<br>print&nbsp;"Ende&nbsp;des&nbsp;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&uuml;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&nbsp;-w<br><br>use&nbsp;strict;<br><br><font color="#0000cc">use&nbsp;lib&nbsp;('subdir');</font><br><br>print&nbsp;"Erste&nbsp;Zeile&nbsp;des&nbsp;Hauptprogramms\n";<br>use&nbsp;modul;<br>print&nbsp;"Ende&nbsp;des&nbsp;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&nbsp;"Ausgabe&nbsp;aus&nbsp;'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&auml;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&nbsp;Grote</a></i>
    </td>
    <td align="right"><i>Version: 2.05 (24.1.2012)</i>
    </td>
  </tr></table>
 </body>
</html>