Peter Fischer
In AppleScript kann auch rekursiv programmiert werden. Rekursive Programmierung bedeutet, daß ein Handler sich selbst aufruft. Damit das Skript nicht in einer Endlosschleife landet, muß genau bestimmt werden, ab wann oder unter welchen Bedingungen der Handler aufhören soll, sich selbst aufzurufen.
Die häufigste Anwendung eines rekursiven Handlers besteht wohl darin, Dateien eines Ordners und dessen Unterordner abzuarbeiten.
Das folgende Beispiel-Skript stammt von Bill Briggs. Es schiebt alle Dateien in den Papierkorb.
Sie werden sich wohl fragen, für was das jetzt gut sein soll. Nun, Sie haben sich mit Sicherheit ein bestimmtes Ordnungs-System geschaffen. Ihre Dateien legen Sie immer in bestimmte Ordner.
Nach einem Backup benötigen Sie die Dateien nicht mehr auf Ihrer Festplatte. Jetzt haben Sie 3 Möglichkeiten.
- Sie löschen die Dateien per Hand aus den jeweiligen Ordnern
- Sie löschen die gesamten Ordner samt Inhalt und legen danach die Ordnerstruktur neu an
- Sie benutzen das folgende Skript
Der "on run"-Handler wird eigentlich nicht gebraucht. Er zeigt jedoch beim Doppelklicken des Skripts eine kleine Kurzanleitung.
on run
display dialog ¬
"So wird das nichts!¬
Ziehen Sie einen Ordner auf das Skript.¬
Alle Dateien, die sich im Ordner befinden,¬
werden dann in den Papierkorb gelegt." buttons {"OK"} ¬
default button 1 with icon caution
end run
Nützlicher ist allerdings dieser "on run"-Handler:
on run
set derOrdner to choose folder
MachWas(derOrdner)
end run
Durch die Verwendung von "choose folder" wird dem Skript die Referenz eines Ordners übergeben.
Bei Verwendung des "on open"-Handlers wird dem Skript nicht die Referenz zu dem Objekt, das man daraufzieht übergeben, sondern eine Liste mit Referenzen. In unserem Fall ist es zwar nur 1 Referenz (die des Top-Level-Ordners), sie muß jedoch zuerst aus der Liste extrahiert werden.
on open derOrdner
set aktuellerOrdner to (item 1 of derOrdner)
MachWas(aktuellerOrdner)
-- Kurzfassung: MachWas(item 1 of derOrdner)
end open
on MachWas(BearbeitungsOrdner)
tell application "Finder"
delete every file of BearbeitungsOrdner
set OrdnerInhalt to ¬
(every item of BearbeitungsOrdner)
repeat with einObjekt in OrdnerInhalt
my MachWas(einObjekt)
end repeat
end tell
end MachWas
Zunächst werden also alle Dateien der obersten Ordnerebene gelöscht. Danach werden die verbleibenden Objekte (das können jetzt nur weitere Ordner sein) in einer Variablen gespeichert. Diese Ordner-Liste wird dann in der repeat-Schleife abgearbeitet, wobei der Handler wiederum aufgerufen wird. Befinden sich also weitere Ordner in einem Ordner, werden diese alle abgearbeitet.
Das Beispiel-Skript zeigt zwar das Prinzip der Rekursion auf, ist aber nicht ganz optimal. Es werden zunächst alle Dateien bearbeitet (in den Papierkorb verschoben) und das was übrig bleibt müssen dann wohl zwangsläufig Ordner sein, die dann nacheinander in der selben Weise abgearbeitet werden.
Dadurch, dass nicht wirklich geprüft wird, ob es sich bei einem Objekt um einen Ordner handelt, ist das Skript nicht universell einsetzbar.
Deshalb hier noch ein anderes Skript.
-- Run-Handler zum debuggen
on run
set theFileList to (choose folder) as list
repeat with theFile in theFileList
File_or_Folder(theFile)
end repeat
end run
on open theFileList -- Per Drag & Drop wird
-- eine Liste mit Referenzen an das Skript übergeben
repeat with theFile in theFileList
File_or_Folder(theFile)
end repeat
end open
-- Prüfung, ob es sich um einen Ordner oder
-- eine Datei handelt
on File_or_Folder(theFile)
set theInfo to info for theFile
if folder of theInfo then -- nicht in einen Finder-Tell-Block setzen!
tell application "Finder"
-- Inhaltsliste des Unterordners erstellen
-- benötigt Finder-Tell-Block für 'every item'
set FolderList to every item of theFile
end tell
repeat with theFolder in FolderList
set theFolder to theFolder as alias -- wichtig für OS X
(* Ohne 'as alias' enthält die Variable 'theFolder' nur
den Namen des Ordners als Unicode Text. *)
-- rekursiver Aufruf des Handlers
my File_or_Folder(theFolder)
end repeat
else
-- Kein Ordner, also Datei bearbeiten
ProcessIt(theFile)
end if
end File_or_Folder
-- Dateien werden bearbeitet
on ProcessIt(theFile)
tell application "Finder"
if locked of theFile = false then
set locked of theFile to true
else
set locked of theFile to false
end if
end tell
end ProcessIt
Ich hoffe, Sie können das hier Gezeigte in Ihren Skripts gebrauchen.
Peter Fischer
|