Calocybe: Ein paar allgemeine Fragen zu Perl

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

  1. hi!

    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:

    Schreibe in die erste Zeile deines Skripts:
    #!/usr/bin/perl -w
    Durch -w gibt Perl Warnungen aus. In deinem Fall solltest du darauf hingewiesen werden, dass die Variable nur an dieser Stelle verwendet wird.

    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?

    Das lässt sich wohl relativ leicht feststellen, indem du ein Skript mit drei Zeilen schreibst ;-)) Die Antwort dürfte JA sein; Perl unterscheidet zwischen Groß- und Kleinschreibung.

    3.  Macht continue einen Sinn?
        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)

    Ich kann nur sagen, ich habe weder den Befehl continue noch redo jemals verwendet, deshalb kann ich dir dazu nicht viel sagen.

    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 |= ?

    Das ist einfach: JA. Folgende gibt es auf jeden Fall: ++, --, +=, *=, -=, /=, ||=, &&=, .=

    5.  Fehler in <../../tgci.htm#a2>?
        Fuer mich als C-Junkie stellt sich das eher so dar:

    So sieht es für mich auch aus. Aber die meisten werden das nicht merken, und es ist ja nur ein Beispiel, wie man eine Subroutine programmiert.

    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?

    open DATEI, "<datei.bin" or die "Fehler!";
    binmode DATEI;
    ...
    close DATEI;

    binmode schaltet auf Binärmodus um. Theoretisch müsste es dann wohl richtig funktionieren.
    Um eine bestimmte Anzahl von Zeichen zu lesen, kannst du die Funktion read verwenden:
      read DATEIHANDLE, SKALAR, LÄNGE [, OFFSET]

    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.

    Ich weiß nicht, wie das HTTP funktioniert. Es handelt sich auf jeden Fall um einen HTTP-Header.

    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?

    Ich würde sagen: ja, genauso müsste es funktionieren.

    bye, Frank!

    1. hi!

      Noch ein Hinweis. Unter <t01765.htm#a7885> habe ich ein paar Bücher aufgeführt, die dir was nützen könnten, wenn du dich richtig mit Perl befassen möchtest.

      bye, Frank!

      1. Hallo Frank :)

        die bücherliste von dir ist gut :) wie eigentlich alle bücher von oreilly, kennst du das Kamel-Book in der orginal fassung? "much better"

        daß das Cookbook klasse ist, das brauchen wir ja nciht mehr zu erwähnen *gg*

        /me hat seinen Senf nich für sich behalten können :)))))

        CU Rufinus

        PS: Kann nicht mehr in den "JAVA" Chat kommen, mein eben eingerichteter Proxy lässt das nicht zu :(
        Stefan!!!! MACH WAS :)

        1. Hallo Rufinus

          PS: Kann nicht mehr in den "JAVA" Chat kommen, mein eben eingerichteter Proxy lässt das nicht zu :(
          Stefan!!!! MACH WAS :)

          Tut mir leid, ich komme problemlos rein, und fuer Deine Proxies kann ich nun wirklich nix <g>

          viele Gruesse
            Stefan Muenz

          1. Tut mir leid, ich komme problemlos rein, und fuer Deine Proxies kann ich nun wirklich nix <g>

            Hast auch recht....gut werd ich das konifg file wieder aufmachen und ein paar schräubchen drehen :))))

            CU
            Rufinus

  2. Hallo Calocybe,

    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?

    Neben dem "-w"-Schalter kannst Du auch noch das Modul strict.pm verwenden. Dieses Modul zwingt Dich, wenn es in seiner reinen Form aufgerufen wird, unter anderem zu Variablendeklarationen und Quoting. Du kannst also selbst entscheiden, wie sehr Du Dich an bestimmte Konventionen fesseln willst. Eingebunden wird es wie in Perl ueblich mit "use". Naehere Informationen siehe Perlmod oder strict.html (bei ActivePerl). Zumindest fuer Win32 liegt strict.pm nach der Installation direkt im Rootverzeichnis von lib.

    z.B.:
    ###############Dateianfang######################
    #!/usr/perl/bin            #je nach System)
    use cgi qw(:standard);     #z.B. CGI-Modul laden)
    use strict;                #Strict-Modul laden

    my(
        $LangerkomplizierterVariablennamen,
        $AndererVariablenname
       );
    #######Hier geht es dann los#################

    Uebrigens kann man auch manche Bloecke im Code dann wieder mit "no strict qw(...); befreien, wenn an einer Stelle die Restrictionen zu sehr stoeren.

    Quellen u.a.:
    -PC-Magazin Spezial 7/98 Thema Perl5 (Sehr gut),
    -Das Gecko-Book für Win32 von O'Reilly (Sehr gut, wenn Perl unter Win32 verwendet werden soll)

    Viel Spass noch, Perl macht suechtig!

    Michael

    1. Viel Spass noch, Perl macht suechtig!

      Michael

      Hallo Michael, da hast du vollkommen recht :-)

      1. Hi,

        Viel Spass noch, Perl macht suechtig!
        Hallo Michael, da hast du vollkommen recht :-)

        stimmt... Mist, ich habe schon 5 Minuten kein Perl mehr programmiert! *zitter* :-)

        Cheatah