Thread Archive::RAR...: treibt mich in den Wahnsinn!
(27 answers)
Opened by zipster at 2005-02-15 18:11
Ich habe mir nicht das gesamte Skript auf Funktionsfaehigkeit angeschaut, aber hier ein paar Bemerkungen. Nimm es einfach mal als Anregungen. ;)
Quote So viele globale Variable sind eigentlich zu viele. Da bietet es sich an, einiges in einem einzigen, globalen Hash auszugliedern (oder gleich ein Config-Modul anlegen). Nachtrag: Offensichtlich brauchst du viele davon sowieso nur lokal, dann deklariere sie doch auch lokal. Quote Wenn du die Datei sowieso zeilenweise durchgehst, brauchst du eigentlich kein Tie::File. Da kannst du sie gleich zeilenweise einlesen. Quote Daran sind mehrere Dinge unschoen: - Du brauchst fast den gleichen Code mehrfach hintereinander. Das waere schon mal besser mit einer Subroutine gemacht. - Das jeweilige Schluesselwort ("backuppfad", "remoteport" etc.) muss zweimal auftauchen => anfaellig fuer Tippfehler. - Die Laenge des Schluesselwortes ist fest kodiert. - Die Regex ist nicht am Zeilenanfang verankert. Abgesehen davon, dass es auf CPAN sehr schoene Module zur Verarbeitung von Konfig.dateien gibt, kann man die Auswertung auch "von Hand" schoener machen: Code: (dl
)
1 my %Config; # Konfigurationshash Dazu noch ein paar Kommentare in die Inidatei - fertig ist die Laube! Quote Du hast eine laestige Angewohnheit, die ich anfangs in Perl auch hatte. :) Meine Vermutung ist, dass man sie sich bei der Shellprogrammierung einfaengt: Du setzt Variablen immer in Anfuehrungszeichen, wenn du ihren Wert haben moechtest, in einer Zuweisung oder bei print. Du schreibst $var2 = "$var1"; statt $var2 = $var1; In dieser Zeile schreibst du die "$!" statt einfach die $!. Umgekehrt machst du die print-Anweisung komplizierter als noetig. print FEHLER "Programm wurde am $datum um $zeit gestartet\n" or die print "$!"; ist kuerzer und einfacher. Quote Hier wieder ein Beispiel: Es gibt keinen Grund, um $ftphost Anfuehrungszeichen zu setzen. Quote Wo etwas als regulaerer Ausdrueck interpretiert wird, sollte man das auch durch die Schreibweise klar machen. Anfuehrungszeichen sind hier also schlecht: Code: (dl
)
if ($answer =~ /keine Zugriffsberechtigung/) Quote Das kann einfach print $socket "$pfad\n"; heissen. Quote Die Sprungmarke brauchst du offensichtlich nicht. Quote Was soll $$anzahl_client sein? $anzahl_client ist doch eine Zahl, keine Referenz. Das muesste also eine Warnung geben. Abgesehen davon kommt mir die Schleifenbedingung sowieso etwas merkwuerdig vor. Meintest du vielleicht while ($anzahl_client < $anzahl_server) ? Mit "eq" vergleicht man auch keine Zahlen, sondern Strings. Bei Zahlen wuerde man mit "==" auf Gleichheit testen. Quote Kuerzer: ++$anzahl_client; Quote $daten{dateien}{$pfad_dateiname}{aenderungsdatum_server} = $aenderungsdatum_server; etc. Quote Statt der Schleife: Code: (dl
)
@pd = sort keys %{$daten{dateien}}; Quote Nun gut, du brauchst @pd eigentlich gar nicht, sondern kannst gleich hier sort keys ... einsetzen. Quote Auch hier sind wieder viele ueberfluessige Anfuehrungszeichen. Andererseits die Frage: Willst du wirklich testen, ob das Aenderungsdatum ungleich Null ist, oder ob es im Hash existiert? Fuer letzteres gibt es exists(). Code: (dl
)
1 unless (exists $daten{dateien}{$zeile}{aenderungsdatum_client}) { Quote Hier meinst du bestimmt auch "!=" statt "ne" (auch wenn es meist keinen Unterschied macht). Quote Auch hier sind wieder viele Wiederholungen. Ich haette die ganze Schleife wahrscheinlich so aehnlich geschrieben: Code: (dl
)
1 @safe_datei = (); Dabei habe ich soweit wie moeglich Variablen lokal beschraenkt ($zeile, $datei_pfad), die somit nicht mehr global deklariert werden muessen. Ausserdem habe ich die ganzen if-Anweisungen in einer - soweit ich sehe gleichwertigen - zusammengefasst und damit keine Codewiederholungen mehr. Quote "erforderlich" Quote Du deklarierst unabsichtlich $dateienfertig in der Schleife neu und weist vorher an $dateienfertig statt $dateiengesamt zu. Du meinst wahrscheinlich: Code: (dl
)
1 my $dateiengesamt = @safe_datei; Quote Damit kannst du dir die aeussere while-Schleife wiederum sparen, oder moechtest du mehrfach durch @safe_datei gehen? Quote Auch hier: if ($counterdatei < 900) ... Quote Hm. Das heisst soviel wie my $i = 1. Falls du $i hochzaehlen moechtest, musst du es ausserhalb der Schleife deklarieren. Quote Code: (dl
)
-archive => "pre_rar$i", Quote Code: (dl
)
unlink @del_rar; Quote Das macht evtl. nicht das, was du meinst. Die erste Regex findet jede Datei, die irgendwo ein beliebiges Zeichen gefolgt von "rar" im Namen hat, also auch "ferrari.jpg" oder "Mehrarbeit.zip"; die zweite findet alle Dateien mit "pre_rar." irgendwo. Das sind zumindest nicht die Dateien, die du angelegt hast, denn die heissen doch eher "pre_rar<nummer>.rar", oder? Auch sollte man - wie oben schon gesagt - Regexen immer als solche schreiben, damit man weiss, dass man auf Sonderzeichen achten muss. Code: (dl
)
if (/^pre_rar\d+\.rar$/) ... # Vorne pre_rar, gefolgt von einer Zahl, gefolgt von .rar am Ende Quote Ueberflussig, es gibt $File::Find::dir. Quote Das sieht grauslich aus, vor allem wenn man sieht, wie schoen du das in den Routinen time() und date() geloest hast. Warum nimmst du hier "scalar localtime (...)", statt gleich mit dem Array zu arbeiten und mit sprintf(), wie unten? Ausserdem benutzt du zweimal $split_time[0] beim Zusammensetzen. Quote Nochmal zur Erinnerung: Code: (dl
)
$daten{dateien}{$File::Find::dir}{aenderungsdatum_client} = $ctime_cl; Ich hoffe, ich konnte dir mit den Kommentaren etwas weiterhelfen. |