Re: mein "Coming-Out" als Perl-Diletant

Datumsansicht Baumansicht Betreffansicht Attachement-Sicht

From: Christian Weisgerber (naddy_at_mips.rhein-neckar.de)
Date: 14. Jul 1999


Michael Lestinsky <michael_at_zaphod.rhein-neckar.de> wrote:

> Ich habe jetzt in langer harter Arbeit endlich das halbwegs lauffähig [*],
> was mich schon lange genervt hat: Ein kleines Script, dass alle
> "*.wav" in einem Verzeichnis in "*.mp3" umwandelt.

Warum du für diese für ein Shellskript prädestinierte Aufgabe unbedingt
Perl verwenden willst, ist mir schleierhaft.

> Vor allem stört mich eines:

<Kopfkratz> Warum korrigierst du es dann nicht?

> Was davon koennte man schoener/besser/schneller machen? (Ja, das
> "glob", ich weiß. ;-)

Naja, auf die csh kommt es bei der restlichen fork/exec-Orgie auch nicht
mehr an.

> #!/usr/bin/perl -w
>

Wenn du hier noch ein

  use strict;

einfügst, was sehr zu empfehlen ist, da »-w« nur die gröbsten Dinge
rausfischt, ...

> $MP3ENCODER = "/home/michael/prog/bin/encode";
> $MP3ENCODERFLAGS = "";
> $FROMDIR = "";
> $TODIR = "";

... dann fliegen dir diese Zuweisungen gleich um die Ohren, weil der
Namensraum der Variablen nicht festgelegt ist. Es ist übrigens in Perl
nicht üblich, Variablennamen ganz in Großbuchstaben zu schreiben, wenn
sie nicht wie Konstanten gebraucht werden.

  my $MP3ENCODE = '/home/michael/prog/bin/encode';
  my $MP3ENCODERFLAGS = '';
  my ($fromdir, $todir);

> sub usage {
> print "Usage: mp3bulk <FROMDIR> <TODIR>\n";
> }
>
> $FROMDIR = $ARGV[0] or &usage;
> $TODIR = $ARGV[1] or &usage;

Das ist natürlich ungeschickt. Der in argv[0] übergebene Programmname
ist in $0 verfügbar, stellt man sinnvollerweise Fehlermeldungen voran
und verwendet ihn bei der Usage. Wenn ein Verzeichnis »0« heißt, erlebst
du eine Überraschung, du möchtest mit defined() prüfen. Die Usage gehört
nach stderr und das Programm danach terminiert, also warum nicht direkt
die() verwenden.

  (my $me = $0) =~ s|.*/||; # Pfad abschneiden
  die "usage: $me fromdir todir\n" if $#ARGV != 1;
  ($fromdir, $todir) = @ARGV;

> print "\nwav2mp3 Version 0.1\n";
> print "(c) 1999 Michael Lestinsky";

Autsch, die PC-Mentalität schlägt zu. Erstens interessiert das keinen,
zweitens ist das keine sinnvoll weiterverwendbare Ausgabe. Wenn schon,
dann mit »print STDERR« oder warn() nach stderr.

> -d $FROMDIR or die "$FROMDIR is not a directory";
> -d $TODIR or die "$TODIR is not a directory";

  ... or die "$me: $fromdir is not a directory\n";

> @WAVFILES = glob("$FROMDIR/*.wav");
>
> foreach $ITEM (@WAVFILES) {

  foreach $item (<$fromdir/*.wav>) {

Da du oben das glob() vermeiden wolltest:

  opendir(D, $fromdir) or die "$me: can't open $fromdir: $!\n";
  foreach $item (grep /\.wav$/, readdir(D)) {
    ...
  }
  closedir(D);

> $ITEM2 = $ITEM;
> # remove leading "./" and substitute ".wav" with ".mp3":
        ^^^^^^^^^^^^^^^^^^^
Warum?

> $ITEM2 =~ s/\.\/(.*)\.wav$/$1.mp3/g;
> $TOFILE = "$TODIR/" . "$ITEM2";

Na, wenn du schon interpolierst, dann

  $tofile = "$todir/$item2";

oder stattdessen

  $tofile = $todir . '/' . $item2;

Aber die Programmlogik stimmt nicht, die Ersetzung setzt ein führendes
»./« voraus, und $todir wird vor $fromdir gestellt, statt dieses zu
ersetzen.

  $tofile = $item;
  $tofile =~ s|.*/([^/]*)\.wav$|$todir/$1.mp3|;

> @args = ($MP3ENCODER, $MP3ENCODERFLAGS, ($ITEM, $TOFILE));
                                              ^ ^
Es sei angemerkt, dass Perl anders als LISP alle Listen flach macht,
verschachtelte Klammerung also gar nichts bewirkt.

> system(@args)==0 or die "system @args failed: $?";

Steht so in der Man-Page, aber normalerweise meckern die Shell oder der
Encoder schon von ganz alleine, $? ist hier nicht wirklich hilfreich,
und die Verarbeitung aller Dateien sollte nicht wegen einem Fehler bei
einer einzelnen abgebrochen werden.

> print "*** Done: $TOFILE\n\n"

Ächz. Wenn schon, dann so, dass man sieht, was passiert:

  print "$tofile ..."
  if (!system @args) {
    print " done.\n";
  }
  else {
    print " error!\n";
  }

Sinnvoller wäre ein optionales Verbosity-Flag, das man an den Encoder
weiterreichen kann, der dann eine echte Fortschrittsanzeige produziert.

-- 
Christian "naddy" Weisgerber                  naddy_at_mips.rhein-neckar.de
    120+ SF Book Reviews: <URL:http://home.pages.de/~naddy/reviews/>


Datumsansicht Baumansicht Betreffansicht Attachement-Sicht

Dieses Archiv wurde generiert von hypermail 2.1.2 : 11. Mar 2002 CET