[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [OT] Python oder Perl



Moin,

* Frank Küster wrote (2005-08-02 10:09):
>Thorsten Haude <debian@thorstenhau.de> wrote:
>>>import os
>>>list = os.listdir('/tmp')
>>>for filename in list:
>>>    print filename,
>>>    if os.path.isdir(filename):
>>>        print "is a directory"
>>>    else:
>>>        print "is a regular file"
>>
>> Wenn ich mal raten darf, was Python macht, sieht das in Ruby so aus:
>>
>> dir = Dir.new('/tmp')
>> dir.each { |filename|
>>     print filename
>>     if filename.stat.directory?
>>         print "is a directory"
>>     else
>>         print "is a regular file"
>>     end
>> }
>>
>> Hm. Auch nicht groß anders. Die Unterschiede kommen wahrscheinlich
>> eher bei größeren Sachen raus.
>
>Naja, ich kenne keine der beiden Sprachen, finde aber trotzdem gleich
>einige Unterschiede:
>
>- Python verwendet die in tausend Sprachen geläufige Syntax "for <name>
>  in <liste> <separator> <body>", während Ruby offenbar sowas macht:
>  "<Kommando_das_liste_produziert> { | <name> | <body> }, das finde ich
>  schwer lesbar (vor allem wenn ich mir vorstelle wie ich das dann von
>  while, until, etc. unterscheiden soll).

Naja, so neu ist das 'each' ja nun auch nicht. Tatsächlich finde ich
diese Schreibweise sehr elegant, man gewöhnt sich auch schnell daran.
Vor allem aber macht es diese Schreibweise sehr einfach, Iteratoren
für eigene Klassen zu schreiben.

Ansonsten kannst Du es auch mit einem foreach haben:

    Dir.foreach('/tmp') { |filename|
        #   block
    }


Mit while würde es vermutlich etwa so aussehen, wie Du es erwarten
würdest:
    while a == b
        #   block
    end


>- Python verwendet zum Erstellen der Liste ein Kommando mit intuitiv
>  verständlichem Namen (os.listdir('<directory>'), Ruby dagegen offenbar
>  ein Suffix .each hinter dem Namen der Variable, die auf das
>  Verzeichnis zeigt.

Nicht ganz, eine Liste wird in Ruby an dieser Stelle nicht erzeugt.
Stattdessen wird an das Objekt dir eine Nachricht geschickt, die in
diesem Fall lautet: "Führe folgenden Block mal für jedes Deiner
Elemente aus." Das erlaubt es, innerhalb der Methode each noch
beliebig komplizierte Dinge anzustellen, bevor man wie gewünscht den
Block aufruft.


>  Das finde ich schon in diesem Fall ungewohnt, und
>  wenn ich mir vorstelle, dass das Verzeichnis nicht in "dir" steckt,
>  sondern in "newplace" oder "wget_target" oder so, wird es noch
>  schwerer.

Warum sollte es dort stecken?


>  Zumal dann, wenn .each auch auf anderen Dingen als
>  Verzeichnissen agieren kann (z.B. URLs oder Datenbank-dingsens).

Wo ist dabei das Problem? Wenn Du Dateien aus einer URL lesen willst,
machst Du vielleicht einen Fehler, oft ist es aber nützlich, wenn Du
Deine Objekte verschiedener Klassen gleich behandeln kannst. In Java
würde man dazu viele Casts verwenden, in Ruby ist das nicht nötig. Das
ist also kein Problem:

    array = Array.new()
    array.push(IO.popen("ls -l"))
    array.push("Hallo Welt!")
    array.push(["Ich", "bin", "ein", "Array"])

Irgendwoanders im Code kannst Du dann alles ausgeben:

    array.each { |thing|
        thing.each { |element|
            print element
        }
    }


>- und schließlich finde ich das Fragezeichen hinter .stat.directory
>  (oder steht es hinter if <test>?) irgendwie albern, aber vielleicht
>  ist das etwas, was man sehr schätzen lernt: Kommandos, die einen
>  Wahrheitswert zurückliefern, haben hinten ein Fragezeichen.

Das Fragezeichen ist Teil des Methodennamens. Es ist nur eine
Konvention, daß Bool'sche Methoden so benannt werden, aber nützlich
ist es allemal.

Es gibt außerdem noch die Konvention, ein ! an den Methodennamen
anzuhängen, wenn das Objekt verändert wird. Zum Beispiel gibt
    array.compact
einfach einen Array zurück, aus dem leere Elemente entfernt werden,
    array.compact!
verändert aber array selbst.


>  Allerdings nur wenn man akzeptiert, dass es Kommandos gibt, die keinen
>  Wahrheitswert zurückliefern.  Ich finde in Perl sehr praktisch dass es
>  die nicht gibt.

Ruby ist an dieser Stelle sehr viel stärker objektorientiert als Perl.
Natürlich ist darum die 0 nicht falscher als die 1, nur false und nil
sind falsch.


Thorsten
-- 
Im übrigen gilt ja hier derjenige, der auf den Schmutz hinweist,
für viel gefährlicher als der, der den Schmutz macht.
    - Kurt Tucholsky

Attachment: pgpfxNRMYcIXk.pgp
Description: PGP signature


Reply to: