run script 命令と同じぐらい話題に上らない store script 命令。ということで、今回は store script 命令。store script 命令っていうのはスクリプトオブジェクトをファイルに保存する命令です。これも個人的には頻繁に使ってます。
基本的な使い方は簡単です。
script StoredScript
on run
display dialog "Hello, World"
end run
end script
store script StoredScript
このスクリプトを実行するとスクリプトを保存する場所を尋ねてくるので、適当な名前を付けて保存します。保存されるのはコンパイル済みスクリプトファイル(拡張子 scpt のファイル)です。
保存されたスクリプトを Script Editor で開いてみると以下のようになっていると思います。
on run
display dialog "Hello, World"
end run
基本的には保存したスクリプトを load script 命令で読み込むことを意識しているのだと思います。store script 命令は。だからでしょうか。スクリプト定義(on script、end script)の部分は削除されています。
実行時にいちいち場所を尋ねられるのも面倒なので、多くの場合 in オプションを使って直接ファイルを指定します。
script StoredScript
on run
display dialog "Hello, World"
end run
end script
set my_path to path to me
tell application "Finder" to set working_folder to folder of my_path as text
set script_file to working_folder & "Stored Script.scpt"
store script StoredScript in file script_file replacing yes
set the_object to load script file script_file
run the_object
このとき、保存先のファイル名の拡張子を「scptd(スクリプトバンドル)」にしておくと、保存されるファイルはスクリプトバンドルになります。
それでは、store script 命令はどういうときに使うのか?
- 一時的なデータの保存
- スクリプトの動的生成
store script 命令はスクリプトオブジェクトを保存するので、一時的なデータやスクリプトの設定などをそのまま書き出すことができます。Property List を使うという方法もありますが、AppleScript のデータをそのまま保存できるので面倒がなくていいです(リストやレコードを保存するなら write 命令を使ってファイルに書き出すこともできますが)。これは、従来からよく利用されている使い方です。
そして、もう一方の「スクリプトの動的生成」。単純にコンパイル済みスクリプトを保存するだけなら関係がないのですが、スクリプトの実行時にスクリプトアプリケーションを動的に生成して処理を分散させたい、ということがあります。
Mac OS X には osacompile というコマンドがあります。store script 命令とこの osacompile を組み合わせるとスクリプトアプリケーションの動的生成が可能になります。例えば、以下のスクリプトはタイマーを動的に生成します。
on Timer(sec)
script Timer
property sentence : "Are you ready? I'm ready."
property period : sec
property wakeup : missing value
on alarm()
say sentence
end alarm
on quit
set wakeup to missing value
tell me to continue quit
end quit
on idle
if wakeup is missing value then
set wakeup to (current date) + period
end if
if (current date) > wakeup then
alarm()
tell me to quit
else
return 1
end if
end idle
on run
tell me to idle
end run
end script
end Timer
property timeList : {"30 seconds", "1 minute", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "30 minutes", "45 minutes", "1 Hour"}
property secondsList : {30, 60, 180, 300, 600, 900, 1800, 2700, 3600}
on run
tell me
activate
set thisItem to choose from list timeList default items (item 1 of timeList) with prompt "タイマーを設定"
if thisItem is false then return
set thisItem to thisItem as text
repeat with i from 1 to count timeList
if item i of timeList is thisItem then exit repeat
end repeat
set sec to item i of secondsList
end tell
set tmpFolder to path to temporary items folder from user domain as text
set desktopFolder to path to desktop as text
set scptFile to tmpFolder & "tmp.scpt"
set appFile to desktopFolder & "Timer-" & (sec as text) & " seconds.app"
store script Timer(sec) in file scptFile replacing yes
do shell script "osacompile -s -o " & quoted form of (POSIX path of appFile) & " " & quoted form of (POSIX path of scptFile)
tell application appFile to run
end run
実行すると時間を尋ねます。時間を設定するとデスクトップにスクリプトアプリケーションを生成します。例えば、時間に 1 分を指定するとアプリケーション起動時から 1 分後にお報せを行い、終了します。生成されたスクリプトアプリケーションは繰り返し使えます。
まぁ、動的生成なんてあまり需要がないかもしれないですが。