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