Hallo!
Am Wochenende habe ich mir das Kapitel CGI/Perl (<../../tg.htm>) durchgelesen
und dabei sind ein paar Fragen aufgetreten, die Ihr mir hoffentlich beantworten koennt.
1. Variablendeklaration
Offensichtlich haelt Perl nichts davon, Variablen zu deklarieren, bevor man sie
benutzen kann. Ich halte das fuer sehr gefaehrlich (aus Erfahrung), man stelle sich
nur folgendes Konstrukt vor:
$LangerKomplizierterVariablenName = 0;
while ($LangerKomplizierterVariablenName < 10) {
# Hier machen wir ganz
# viele, tolle Sachen
LangerKomplizirterVariablenName ++; # man beachte die Schreibweise von Komplizirt
# und noch mehr Sachen
}
Wie dieses Beispiel zeigt, besteht ein grosse Gefahr, dass man sich durch simples
Verschreiben eine Endlosschleife einhandelt. Selbst Microsoft hat das erkannt
(traut man denen ja gar nicht zu) und bietet in Visual Basic die Moeglichkeit, die
Zeile "Option Explicit" am Anfang eines Code-Modul einzufuegen, woraufhin die
fehlende Deklaration einer Variablen zu einer Fehlermeldung fuehrt. Also gibt
es da in Perl irgendeine Moeglichkeit, solche simplen Fehler erkenn zu lassen?
2. Wird Gross-/Kleinschreibung unterschieden?
Zwar wird in <../..//tgca.htm#a5> erwaehnt, wie ein Bezeichner auszusehen
hat, und dass sowohl Gross- als auch Kleinbuchstaben ERLAUBT sind, jedoch nicht ob
diese UNTERSCHIEDEN werden. Als ist jetzt variable dasselbe wie VARIABLE
oder nicht?
3. Macht continue einen Sinn?
In <../../tgce.htm> werden Schleifen behandelt. Ziemlich am Ende wird
folgendes Beispiel aufgefuehrt (Abschnitt "Sprungbefehle", Beispiel 2):
while($i < 10) {
++$i;
if($i % 2 != 0) {
redo;
}
}
continue {
print $i, "\n";
}
Bei jeder ungeraden Zahl wird redo ausgefuehrt, also die while-Schleife erneut
begonnen (genau das, was in C continue macht). Der continue-Block wird immer
ausgefuehrt, wenn der while-Block vorher vollstaendig ausgefuehrt wurde, also
nicht mit redo vorzeitig am Anfang fortgesetzt wurde. Mir scheint das etwas sinnlos
kompliziert zu sein. Folgender Code wuerde doch dasselbe bewirken:
while($i < 10) {
++$i;
if($i % 2 != 0) { redo; }
print $i, "\n";
}
Stimmt doch, oder? Also nun meine Frage: Gibt es fuer das Perl-continue ein
sinnvolles Beispiel, oder wollte der Erfinder von Perl seine Sprache einfach etwas
von C abheben, oder handelt es sich hier schlicht und einfach um einen Fehler in
SELFHTML? (Habe die Beispiele nicht ausprobiert)
4. Operatoren
In <../../tgcf.htm> werden zwar die Berechnungsoperatoren ++, --, += und
-= erwaehnt, was ja aequivalent zu C ist. Aber gibt es in Perl nicht auch solche
wie *=, /=, &= und |= ?
5. Fehler in <../../tgci.htm#a2>?
Dort steht folgendes Beispiel:
$x = &Rechne(1 + 2 * 3 + 4 * 5 + 6 * 7 + 8 * 9);
print $x, "\n";
sub Rechne {
return eval($_[0]);
}
Als Erkaerung steht (sinngemaess), dass der Funktion Rechne der Ausdruck
1 + 2 * 3 + 4 * 5 + 6 * 7 + 8 * 9 komplett uebergeben wird, dort zu 141 ausgwertet
wird (mittels eval()) und dieses Ergebnis zur weiteren Verarbeitung (print)
zurueckgegeben wird. Stimmt das? Fuer mich als C-Junkie stellt sich das eher so dar:
Der Ausdruck wird bereits vor dem Funktionsaufruf durch den Interpreter ausgewertet,
fuer den solch eine simple Rechnung sicher keine Probleme macht. Das Ergebnis (141)
wird an die Funktion uebergeben, sodass dort schlicht und einfach eval(141)
durchgefuehrt wird, was voellig ueberaschenderweise 141 zurueckgibt. Man koennte
dies sicher einfach mit print $_[0] (in der sub Rechne) ueberpruefen. Jedenfalls
faende ich Stefan's Erklaerung logischer, wenn er
$x = &Rechne("1 + 2 * 3 + 4 * 5 + 6 * 7 + 8 * 9"); geschrieben haette, also den
ganzen Ausdruck in Anfuehrungszeichen eingeschlossen.
6. Binaerdateien lesen
In <../../tgcj.htm#a2> wird das Lesen von Dateien behandelt. Mit der
Funktion getc lassen sich Dateien zeichenweise einlesen, was bei Binaerdateien wohl
noetig ist, denn so etwas wie blockweises Einlesen (1000 Bytes in einem Rutsch) gibt
es in Perl vermutlich nicht. Am Ende der Datei wird das Zeichen 00 zurueckgegeben.
Nun ist 00 selbst aber ein in Binaerdateien ziemlich haeufig vorkommendes Zeichen.
Und das heisst, das sich Binaerdateien mit getc praktisch nicht lesen lassen.
Gibt es da einen anderen Weg?
7. Der MIME-Typ
print "Content-type: text/html\n\n";
Diese Zeile sieht man im Zusammenhang mit CGI des oefteren. Wirklich erklaert ist
sie in SELFHTML jedoch nicht. Ich vermute, dies ist eine Konvention der CGI-
Schnittstelle, welche dann im HTTP-Header den entsprechenden MIME-Typ notiert,
jedoch ohne das "Content-type: " und die beiden Zeilenvorschuebe.
Jetzt ueberlege ich mir, eine ZIP-Datei zum Download zur Verfuegung zu stellen,
jedoch nicht bevor der Leser sich identifiziert hat (mit Namen und EMail-Adresse).
Klar, er kann luegen, ist jetzt aber erstmal egal. Wichtig ist: Kann ich jetzt mit
print "Content-type: application/x-zip-compressed\n\n";
eine .ZIP-Datei ankuendigen und dann mit print "\x50\x4B\x03\x04" die Daten einfach
binaer rueberschieben? (50 4B 03 04 ist uebrigens der Beginn einer ZIP-Datei,
jedenfalls einer die von WinZip produziert wurde.)
Vielen Dank fuer Eure Hilfe, Hinweise und Meinungen
Calocybe