1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>SELFHTML: Perl / Perl-Sprachelemente / Subroutinen</title>
<link rel="stylesheet" type="text/css" href="../../src/selfhtml.css">
<meta name="description" content="Was Subroutinen in Perl sind, und wie sie definiert werden.">
<meta name="keywords" content="SELFHTML, Perl, Subroutinen, Unterprogramme, Funktionen, Rckgabewert, Returnwert, Parameter">
<meta name="author" content="Redaktion SELFHTML, selfhtml81@selfhtml.org">
<meta name="robots" content="noindex, nofollow">
<meta name="DC.Publisher" content="SELFHTML e. V.">
<meta name="DC.Date" content="2005-11-09T00:29:27+01:00">
<meta name="DC.Identifier" content="http://de.selfhtml.org/perl/sprache/subroutinen.htm">
<meta name="DC.Language" content="de">
<meta name="DC.Rights" content="../../editorial/copyright.htm">
<meta name="DC.Date.created" content="2001-10-27T08:00+01:00">
<meta name="SELF.Pagetype" content="page">
<link rel="alternate" type="application/atom+xml" title="SELFHTML-Weblog (Atom, gesamt)" href="http://aktuell.de.selfhtml.org/weblog/atom-feed">
<link rel="alternate" type="application/rss+xml" title="SELFHTML-Weblog (RSS, Auszge)" href="http://aktuell.de.selfhtml.org/weblog/rss-feed">
<link rel="shortcut icon" type="image/x-icon" href="../../src/favicon.ico">
<link rel="author" title="Impressum" href="../../editorial/impressum.htm">
<link rel="contents" title="Inhaltsverzeichnis" href="../../navigation/inhalt.htm">
<link rel="index" title="Stichwortverzeichnis" href="../../navigation/stichwort.htm">
<link rel="search" title="Suche" href="../../navigation/suche/index.htm">
<link rel="help" title="Hilfe" href="../../editorial/index.htm">
<link rel="copyright" title="Urheberrecht" href="../../editorial/copyright.htm">
<link rel="top" title="SELFHTML" href="../../index.htm">
<link rel="up" title="Perl-Sprachelemente" href="index.htm">
<link rel="next" title="Tokens" href="tokens.htm">
<link rel="prev" title="Regulre Ausdrcke" href="regexpr.htm">
<link rel="first" title="CGI-notwendige Anweisungen in Perl" href="cginotwendig.htm">
<link rel="last" title="CGI-typische Aufgaben in Perl" href="cgitypisch.htm">
</head>
<body>
<table cellpadding="4" cellspacing="0" border="0" width="100%">
<tr>
<td colspan="2" class="nav"><a class="an" name="top"><img src="../../src/refkap.gif" width="16" height="13" alt="Teil von"></a> <a href="../../index.htm">SELFHTML</a>/<a href="../../navigation/index.htm" target="_parent" class="navh">Navigationshilfen</a> <img src="../../src/refkap.gif" width="16" height="13" alt="Teil von"> <a href="../index.htm">Perl</a> <img src="../../src/refkap.gif" width="16" height="13" alt="Teil von"> <a href="index.htm">Perl-Sprachelemente</a></td>
</tr>
<tr>
<td class="doc" width="110"><a href="../../index.htm"><img src="../../src/logo.gif" width="106" height="109" border="0" alt="SELFHTML"></a></td>
<td class="docbot" width="100%"><h1 class="ph1">Subroutinen</h1></td>
</tr>
<tr>
<td class="doctop">
<img src="../../src/dokx.gif" width="30" height="20" vspace="6" alt="Informationsseite">
</td>
<td valign="top" nowrap="nowrap">
<p>
<img src="../../src/down.gif" width="14" height="10" alt="nach unten"> <a href="#erstellen">Subroutinen erstellen</a><br>
<img src="../../src/down.gif" width="14" height="10" alt="nach unten"> <a href="#parameter">Subroutinen mit Parametern aufrufen</a><br>
<img src="../../src/down.gif" width="14" height="10" alt="nach unten"> <a href="#rueckgabewerte">Rckgabewerte bei Subroutinen</a><br>
</p>
</td>
</tr><tr><td colspan="2" class="doc"> <a href="#bottom"><img src="../../src/down.gif" width="14" height="10" border="0" alt="nach unten"></a> </td></tr>
</table>
<h2><a class="an" name="erstellen">Subroutinen erstellen</a></h2>
<p>Bei komplexeren Perl-Scripts ist es empfehlenswert, bestimmte Programmteile in selbst definierte Unterprogramme oder Funktionen zu verlagern - so genannte Subroutinen. Auf diese Weise knnen Sie das Script besser strukturieren. Sinnvoll ist das vor allem bei Programmteilen, die im Laufe des Scripts mehrmals ausgefhrt werden. Bevor Sie also eine grere Prozedur mehrmals im Script notieren, sollten Sie die entsprechende Prozedur in eine Subroutine stecken und diese Subroutine an der gewnschten Stelle aufrufen.</p>
<h3 class="xmp"><a class="an" name="beispiel1">Beispiel eines vollstndigen CGI-Scripts in Perl:</a></h3>
<p><img src="../../src/dokf.gif" width="15" height="10" alt="Beispiel-Seite"> <a href="http://de.selfhtml.org/cgi-bin/812/subroutinen1.pl">Anzeigebeispiel: So sieht's aus</a> (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)</p>
<pre>
#!/usr/bin/perl -w
use strict;
use CGI::Carp qw(fatalsToBrowser);
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Test</title></head><body>\n";
my $Ergebnis = 1 + 2 * 3 + 4 * 5 + 6 * 7 + 8 * 9;
Ausgabe();
$Ergebnis = sqrt(sqrt(81));
Ausgabe();
print "</body></html>\n";
sub Ausgabe {
print "Das Ergebnis lautet: <b>$Ergebnis</b><br>\n";
}
</pre>
<h3 class="xpl">Erluterung:</h3>
<p>Im Beispiel wird eine Subroutine mit dem Namen <code>Ausgabe</code> erstellt. Eine Subroutine beginnt mit dem Schlsselwort <code>sub</code>. Dahinter folgt ein frei whlbarer Name, der den <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="../intro.htm#namensvergabe">Namenskonventionen</a> von Perl entsprechen muss. Der gesamte Inhalt der Subroutine muss in <strong>geschweiften</strong> Klammern stehen. Sie knnen beliebige und beliebig viele Anweisungen innerhalb der Subroutine notieren.</p>
<p>Mit ihrem Namen und runden Klammern dahinter rufen Sie eine Subroutine auf. Der Aufruf ist eine eigene Anweisung, muss also wie andere Anweisungen mit einem Semikolon abgeschlossen werden. Im obigen Beispiel kommt zweimal die Anweisung <code>Ausgabe();</code> vor. Dadurch wird die Subroutine mit dem Namen <code>Ausgabe</code> aufgerufen.</p>
<h3 class="inf">Beachten Sie:</h3>
<p>Anweisungen in Subroutinen werden nur ausgefhrt wenn die Subroutine aufgerufen wird.</p>
<p>Es ist egal, an welcher Stelle im Script eine Subroutine steht. Sie kann im Prinzip berall stehen. Es ist allerdings sinnvoll, alle Subroutinen optisch getrennt vom direkt ausgefhrten Hauptprogramm zu notieren.</p>
<p>Beim Aufruf knnten Sie anstelle von <code>Routine();</code> auch <code>&Routine;</code> oder <code>&Routine();</code> notieren. Die erste Art ist jedoch am empfehlenswertesten, vor allem bei Aufrufen ohne Klammern kann es zu Fehlern kommen.</p>
<p>Wenn Sie - wie im obigen Beispiel - mit <code>use strict;</code> arbeiten, mssen Sie bekanntlich alle Variablen vor ihrer ersten Verwendung deklarieren. Damit wird aber auch der Geltungsbereich einer Variablen eingeschrnkt. Eine Subroutine stellt einen eigenen Block und Geltungsbereich dar. Wenn Sie also beispielsweise innerhalb einer Subroutine mit <code>my $Variable=1;</code> eine Variable deklarieren und im Hauptprogramm versuchen, mit <code>print $Variable</code> den Inhalt auszugeben, fhrt dies zu einer Fehlermeldung, da <code>$Variable</code> im Hauptprogramm nicht bekannt ist. Umgekehrt ist es anders: Variablen, die im Hauptprogramm deklariert sind, sind auch in Subroutinen verfgbar. Im obigen Beispiel wird ja von dieser Mglichkeit Gebrauch gemacht. Generell ist es auch aus diesem Grund bei greren Scripts sinnvoll, mglichst viel Code mit Variablendeklarationen in Subroutinen zu packen und im Hauptprogramm so wenig Variablendeklarationen wie mglich zu haben. Denn globale Variablen knnen tendenziell leichter zu logischen Fehlern im Programmablauf fhren, da sie nicht so leicht zu kontrollieren sind wie Variablen in begrenzten Subroutinen.</p>
<p>Das berschreiben von vordefinierten Perl-Funktionen ist ebenfalls mglich. Wenn Sie zum Beispiel die Funktionsweise einer vordefinierten Funktion ergnzen mchten, definieren Sie einfach eine neue Subroutine mit dem entsprechenden Namen. Einige Perl-Module machen von dieser Mglichkeit Gebrauch. Um auf die ursprngliche Funktion zuzugreifen, setzen Sie einfach ein <code>CORE::</code> vor den Namen.</p>
<p class="doc"><a href="#top"><img src="../../src/up.gif" width="14" height="10" border="0" alt="nach oben"></a><a href="#bottom"><img src="../../src/down.gif" width="14" height="10" border="0" alt="nach unten"></a></p>
<h2><a class="an" name="parameter">Subroutinen mit Parametern aufrufen</a></h2>
<p>Beim Aufruf knnen Sie einer Subroutine Daten bergeben, die von der Subroutine verarbeitet werden sollen.</p>
<h3 class="xmp"><a class="an" name="beispiel2">Beispiel eines vollstndigen CGI-Scripts in Perl:</a></h3>
<p><img src="../../src/dokf.gif" width="15" height="10" alt="Beispiel-Seite"> <a href="http://de.selfhtml.org/cgi-bin/812/subroutinen2.pl">Anzeigebeispiel: So sieht's aus</a> (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)</p>
<pre>
#!/usr/bin/perl -w
use strict;
use CGI::Carp qw(fatalsToBrowser);
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Test</title></head><body>\n";
formatHTML("Hallo User","h1");
formatHTML("Dein Browser gibt sich aus als $ENV{HTTP_USER_AGENT}","i");
print "</body></html>\n";
sub formatHTML {
my $Inhalt = shift;
my $Format = shift;
print "<$Format>$Inhalt</$Format>";
}
</pre>
<h3 class="xpl">Erluterung:</h3>
<p>Das Beispiel definiert eine Subroutine namens <code>formatHTML</code>. Im oberen Teil des Scripts knnen Sie sehen, wie diese Subroutine aufgerufen wird. Mit dem Aufruf <code>formatHTML("Hallo User","h1");</code> werden der Subroutine zwei Parameter bergeben. Denn die Subroutine soll die Aufgabe haben, aus einem bergebenen Text und einem bergebenen HTML-Elementnamen ein HTML-Konstrukt, bestehend aus Anfangs-Tag, Inhalt und End-Tag auszugeben.</p>
<p>Die Subroutine erwartet also zwei Parameter. Interessant ist, wie sie die Parameter abfragt. Dazu benutzt sie einfach die Perl-Funktion <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="../funktionen/listenhashes.htm#shift">shift</a> und weist deren Rckgabewert einem Skalar zu. Um diese Anweisung zu verstehen, ist es wichtig zu wissen, dass Parameter, die einer Subroutine bergeben werden, in der <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="vordefiniert.htm">vordefinierten Variablen</a> <code>@_</code> stehen. Diese Variable enthlt die Liste aller Parameter, die der Subroutine bergeben wurden. Der erste Parameter steht dann in <code>$_[0]</code>, der zweite in <code>$_[1]</code> usw. Eleganter ist es jedoch, sich die Parameter mit der <code>shift</code>-Funktion zu holen. Da <code>shift</code> beim Aufruf kein Parameter bergeben wird, wendet die Funktion ihre Arbeit automatisch auf die vordefinierte Variable <code>@_</code> an. Die Funktion entfernt das erste Element der Liste und gibt es zurck. Durch wiederholtes Aufrufen von <code>shift</code> kann sich eine Subroutine also nach und nach alle Parameter abholen, die ihr bergeben wurden.</p>
<p>Die Subroutine im Beispiel holt sich also den ersten Parameter und speichert ihn in <code>$Inhalt</code> und den zweiten in <code>$Format</code>. Dann erzeugt sie eine <code>print</code>-Ausgabe und baut darin das gewnschte HTML-Konstrukt zusammen. Bei jedem Aufruf aus dem Hauptprogramm bewirkt die Subroutine also eine Ausgabe im Browser mit den bergebenen Parametern.</p>
<h3 class="inf">Beachten Sie:</h3>
<p>Sie mssen nirgendwo festlegen, wie viele und welche Parameter eine Subroutine bergeben bekommen kann. Eine Subroutine, die nicht wei, wie viele Parameter sie bergeben bekommt, kann die bergebene Parameterliste beispielsweise mit einer <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="schleifen.htm#foreach">foreach-Schleife</a> in der Form <code>foreach(@_)</code> abarbeiten.</p>
<p class="doc"><a href="#top"><img src="../../src/up.gif" width="14" height="10" border="0" alt="nach oben"></a><a href="#bottom"><img src="../../src/down.gif" width="14" height="10" border="0" alt="nach unten"></a></p>
<h2><a class="an" name="rueckgabewerte">Rckgabewerte bei Subroutinen</a></h2>
<p>Subroutinen knnen Werte zurckgeben. Subroutinen, die Parameter bergeben bekommen, damit etwas tun und die verarbeiteten Daten zurckgeben, entsprechen am ehesten dem, was man unter einer <strong>Funktion</strong> versteht. Die eingebauten <img src="../../src/kap.gif" width="15" height="13" alt="Kapitel"> <a href="../funktionen/index.htm">Perl-Funktionen</a> folgen diesem Schema, aber auch die meisten Subroutinen, die Sie in <img src="../../src/kap.gif" width="15" height="13" alt="Kapitel"> <a href="../module/index.htm">Modulen</a> aufrufen knnen, arbeiten als Funktionen.</p>
<h3 class="xmp"><a class="an" name="beispiel3">Beispiel eines vollstndigen CGI-Scripts in Perl:</a></h3>
<p><img src="../../src/dokf.gif" width="15" height="10" alt="Beispiel-Seite"> <a href="http://de.selfhtml.org/cgi-bin/812/subroutinen3.pl">Anzeigebeispiel: So sieht's aus</a> (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)</p>
<pre>
#!/usr/bin/perl -w
use strict;
use CGI::Carp qw(fatalsToBrowser);
print HTMLKopf();
print HTMLCode("h1","Hallo!","font-size:24pt; color:red");
print HTMLCode("p","Wie geht's?","");
print HTMLFuss();
sub HTMLKopf {
my $Kopf = "Content-type: text/html\n\n".
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'."\n".
"<html><head><title>Test</title></head><body>\n";
return($Kopf);
}
sub HTMLFuss {
my $Fuss = "<hr>\n<script type=\"text/javascript\"><!--\n".
"document.write(\"URL-Adresse: \"+document.URL);\n//--></script>\n".
"</body></html>\n";
return($Fuss);
}
sub HTMLCode {
my $Tag = shift;
my $Inhalt = shift;
my $Style = shift;
unless(defined($Style) and length($Style)) {
return("<$Tag>$Inhalt</$Tag>");
}
else {
return("<$Tag style=\"$Style\">$Inhalt</$Tag>");
}
}
</pre>
<h3 class="xpl">Erluterung:</h3>
<p>Das Beispiel weitet die Subroutinen-Technik zum Erzeugen von HTML-Code weiter aus. Es gibt insgesamt drei Subroutinen: <code>HTMLKopf</code> und <code>HTMLFuss</code> setzen mit Hilfe des <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="operatoren.htm#zeichenkettenverknuepfung">Operators fr Zeichenkettenverknpfung</a> HTML-Code in einem Skalar zusammen. Am Ende wird dieser Skalar mit der Funktion <code>return</code> zurckgegeben.</p>
<p>Etwas komplexer ist die Subroutine <code>HTMLCode</code>. Sie erwartet drei <img src="../../src/up.gif" width="14" height="10" alt="nach oben"> <a href="#parameter">Parameter</a>, nmlich einen fr das zu erzeugende HTML-Element, einen fr dessen Inhalt, und einen fr eventuelle CSS-Eigenschaften zur Formatierung des Elements. Abhngig davon (mit <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="bedingt.htm#if_else_elsif">if/else</a> wird die entsprechende Weiche gestellt), ob der dritte Parameter einen Inhalt hat, wird der gewnschte HTML-Code zusammengesetzt und das gesamte Konstrukt mit <code>return</code> zurckgegeben.</p>
<p>Im Hauptprogramm stehen nur ein paar <code>print</code>-Anweisungen. Die Funktion <code>print</code> ist so leistungsfhig, dass sie als bergebene Parameter fr das, was sie ausgeben soll, auch Aufrufe anderer Funktionen oder eigener Subroutinen erlaubt. Genau davon wird im Beispiel Gebrauch gemacht. Ausgegeben wird dabei der <strong>Return-Wert</strong> der jeweils aufgerufenen Subroutine. Ebenso knnten Sie den Return-Wert natrlich einer Variablen zuordnen oder etwas anderes damit tun.</p>
<h3 class="inf">Beachten Sie:</h3>
<p>Subroutinen knnen alle Arten von Variablen zurckgeben, also neben <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="skalare.htm">Skalaren</a> auch <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="listen.htm">Listen/Arrays</a>, <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="hashes.htm">Hashes</a> und <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="referenzen.htm">Referenzen</a>. Die aufrufende Anweisung muss dafr sorgen, dass der zurckgegebene Wert im richtigen Variablenformat gespeichert wird. Wenn in einer Subroutine namens <code>TeileErmitteln</code> beispielsweise notiert ist:<br>
<code>return(@Ermittelte);</code><br>
dann knnte eine aufrufende Anweisung etwa lauten:<br>
<code>my @Teile = TeileErmitteln();</code><br>
Falls Aufrufspeicher und Rckgabewert nicht vom gleichen Typ sind, greift automatisch die Kontext-Bewertung von Perl. Wenn Sie beispielsweise die gleiche Subroutine aufrufen mit:<br>
<code>my $Ergebnis = TeileErmitteln();</code><br>
Dann ist das, als ob da stnde: <code>$Ergebnis = @Ermittelte</code>. Das Ergebnis besteht in dem Fall darin, dass in <code>$Ergebnis</code> die Anzahl der zurckgegebenen Array-Elemente steht, weil Perl bei einer Liste im skalaren Kontext die Anzahl der Array-Elemente liefert.</p>
<table cellpadding="4" cellspacing="0" border="0" width="100%">
<tr><td colspan="2" class="doc">
<a href="#top"><img src="../../src/up.gif" width="14" height="10" border="0" alt="nach oben"></a>
</td></tr>
<tr><td class="doc"><a href="tokens.htm"><img src="../../src/next.gif" width="10" height="10" border="0" hspace="10" alt="weiter"></a></td>
<td width="100%"><img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="tokens.htm">Tokens</a>
</td></tr>
<tr>
<td class="doc"><a href="regexpr.htm"><img src="../../src/prev.gif" width="10" height="10" border="0" hspace="10" alt="zurck"></a></td>
<td><img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="regexpr.htm">Regulre Ausdrcke</a>
</td>
</tr>
<tr><td colspan="2" class="doc"> </td>
</tr>
<tr>
<td colspan="2" class="nav"><a class="an" name="bottom"><img src="../../src/refkap.gif" width="16" height="13" alt="Teil von"></a> <a href="../../index.htm">SELFHTML</a>/<a href="../../navigation/index.htm" target="_parent" class="navh">Navigationshilfen</a> <img src="../../src/refkap.gif" width="16" height="13" alt="Teil von"> <a href="../index.htm">Perl</a> <img src="../../src/refkap.gif" width="16" height="13" alt="Teil von"> <a href="index.htm">Perl-Sprachelemente</a></td>
</tr>
</table>
<p>© 2007 <img src="../../src/dok.gif" width="15" height="10" alt="Seite"> <a href="../../editorial/impressum.htm">Impressum</a></p>
</body>
</html>
|