store script 命令でスクリプトの動的保存

run script 命令と同じぐらい話題に上らない store script 命令。ということで、今回は store script 命令。store script 命令っていうのはスクリプトオブジェクトをファイルに保存する命令です。これも個人的には頻繁に使ってます。

基本的な使い方は簡単です。

Script Editor で開く

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 Editor で開く

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 命令はどういうときに使うのか?

  1. 一時的なデータの保存
  2. スクリプトの動的生成

store script 命令はスクリプトオブジェクトを保存するので、一時的なデータやスクリプトの設定などをそのまま書き出すことができます。Property List を使うという方法もありますが、AppleScript のデータをそのまま保存できるので面倒がなくていいです(リストやレコードを保存するなら write 命令を使ってファイルに書き出すこともできますが)。これは、従来からよく利用されている使い方です。

そして、もう一方の「スクリプトの動的生成」。単純にコンパイル済みスクリプトを保存するだけなら関係がないのですが、スクリプトの実行時にスクリプトアプリケーションを動的に生成して処理を分散させたい、ということがあります。

Mac OS X には osacompile というコマンドがあります。store script 命令とこの osacompile を組み合わせるとスクリプトアプリケーションの動的生成が可能になります。例えば、以下のスクリプトはタイマーを動的に生成します。

Script Editor で開く

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 分後にお報せを行い、終了します。生成されたスクリプトアプリケーションは繰り返し使えます。

まぁ、動的生成なんてあまり需要がないかもしれないですが。

0 件のコメント :

コメントを投稿