巨大なスクリプトを作るには …

1996.12.3


 行数が100行程度のスクリプトを組むときにはそうでもないですが、ある程度以上大きなスクリプトを組んでいると、色々な問題が生じてきます。特に32KBを越えるスクリプトを組もうとすると、そのままではもう「スクリプト編集プログラム」で扱えなくなってしまいます。(これはスクリプト編集プログラムの制限で、AppleScriptの制限ではありません)

 もちろん32KBものスクリプトを組む人はあまりいないでしょうが、ちょっと大きいスクリプトになると「ファイルのオープンが遅い」「コンパイルが遅い」で、どんどん修正しにくくなってきます。また、大きなスクリプトを組むときにはスクリプトをサブルーチンでブロック化している場合が多いですが、そこそこ作業が進んでくると、もう変更しないルーチンが沢山できてきます。しかしコンパイルではそういう部分もすべて構文確認し直すので、必要以上に時間をとられてしまいます。

 そこで、大きすぎるスクリプトを分割したり、ライブラリや変更しないルーチンをまとめて別ファイルに保存したりする必要がでてきます。こういったときに便利なのが、「スクリプトのロード」です。


スクリプトのロード
Load Script

 AppleScriptでは、スクリプトファイルの読み込み、保存、実行を「スクリプティング機能追加」でサポートしています。ここに関係するのは「読み込み」だけなので、他の部分についてはリファレンスを参考にして下さい。

 さて、スクリプトを別ファイルに保存するにはどうしたら良いでしょうか。答は簡単。「普通にスクリプトファイルやスクリプトアプリケーションとして保存する」だけです。(テキストファイルは不可)

 あとはそのファイル(アプリケーション)を他のスクリプトアプリケーションから読み込むことで、その中に含まれるサブルーチンや属性を利用できます。

 例えば、次のようなスクリプトをファイル名「Lib」として保存してみましょう。

    -- 現在起動しているアプリケーションの名前を得るスクリプト

    on AppNames()
      tell application "Finder"
        set AppList to name of every process
      end tell
      return AppList
    end AppNames

 話を簡単にするために、このファイルは「スクリプト編集プログラム」と同じ階層に保存して下さい。

 さて、次はこのスクリプトを他のファイルに読み込む必要があります。スクリプト編集プログラムに次のように書き込んで実行してみましょう。

    set LibScript to (load script file "Lib")
    tell LibScript to AppNames()

 「結果」ウィンドウに、そのとき立ち上がっているアプリケーション名が列挙されると思います。

 上の例の場合、変数「LibScript」にはスクリプトオブジェクトが格納されており、そのオブジェクトはアプリケーションと同様に扱うことができます。


 では、実際に自分の作成しているスクリプトを、分割して利用することを考えてみましょう。

 まず、自分のスクリプトをうまく切り分ける必要があります。スクリプトを作成しているときは、ついつい勢いで一つのルーチンを長く書いてしまいますが、きりのいいところでうまくサブルーチンに分離できないか工夫してみて下さい。うまく分ければ、非常にすっきりと見やすいスクリプトになると思います。

 ここで注意が一つ。グローバル変数はできるだけ避けましょう。複数のハンドラに共通の変数は、ファイルを分割するとき非常にじゃまになります。ルーチンが別ファイルになる可能性を考えて、あるいは他のスクリプトで再利用するために、ハンドラ内ではローカル変数のみを使用した方が無難です。

 スクリプトをうまくサブルーチンにまとめられたら、後は別ファイルに保存するだけでいいでしょう。保存する場所はどこでも構いませんが、できるだけ本体の存在するディレクトリに保存した方がいいと思います。もちろんライブラリを収めるためのフォルダを作成してもいいですが、その場合にはスクリプトファイルを特定するルーチンを別に書く必要があります。


 次に、スクリプトをどういう風に読み込むか考えてみます。

 まず、一番簡単な方法は、読み込む側のスクリプトの最初の部分でファイルを読み込むことです。この場合スクリプトの収められる変数はグローバル宣言するか、属性(property)として定義しておいて下さい。

    global LibScript
     (または、property LibScript : "" )

    on run
      set LibScript to (load script file "Lib")
        c
    end run

 この方法のいいところは、スクリプトを実行するたびにスクリプトファイルを読み込むことです。つまりスクリプトファイル側を書き換えれば、読み込む側のスクリプトに必ずその変更が反映されます。

 ただ、スクリプトファイルを書き換えない場合は、一度読み込めばそれで十分です。そんなときには、次のようにして下さい。

    property pLibScript : (load script file "Lib")

    on run
      c
    end run

 こうすることで、ファイルを読み込むのは最初に起動したとき一度だけになります。もちろんこの場合、スクリプトファイルを後で変更してもその内容は反映されませんので、外部からporpertyを再設定するか、スクリプトを開いて再コンパイルする必要があります。

 再設定の方法としては、下のようなリセット用のサブルーチンをスクリプトに組み込んでおく方法がいいでしょう。

    on ResetLib ()
      set pLibScript to (load script file "Lib")
    end ResetLib

 読み込む側のスクリプトアプリケーションの名前を「New Script」とすると、外部からは次のようにすれば再設定できます。

    tell application "New Script" to ResetLib ()

註)
 外部からサブルーチンを操作するには、そのスクリプトアプリケーションが「実行後、自動的に終了しない」オプションをチェックした状態で保存されている必要があります。


 実例を挙げましょう。

 このホームページの中で、AppleScriptとファイルメーカー Proを連携して作成しているページがあります。「サンプルスクリプト」のページからリンクされている4ページ分がそうなのですが、このページ、4ページともかなり作り方が違うので、それぞれ異なったスクリプトを作成する必要がありました。このスクリプトを一つのアプリケーションとして作成しようとすると、内蔵するテキストも含め28KBになってしまいます。そこで、それぞれを別のファイルに収めることにしました。

Picture of A Folder

 この図を見てもらえば分かりますが、それぞれのスクリプトはすべてドロップレットとして保存してあります。これは、一つ一つのスクリプトをデバッグするのにその方が都合がいいからで、スクリプトはすべて、それ単体で動作するようにしてあります。

 ちなみに「AllListChange HTML」というドロップレットが4種類すべてのリストを書き出すためのスクリプトで、下に並んでいる4つの「 ... HTML」というのがそれぞれのファイルを書き出すスクリプトになっています。

 この例ではページの模様替えに際して常にそれぞれのドロップレットを更新する可能性があるので、毎回スクリプトファイルを読み込む作りにしてあります。もしスクリプトファイルを変更しないなら、属性として最初に読み込むだけのスクリプトにしてもいいのですが。



 ということで、巨大なスクリプトを作成するときのTipsでした。この方面を詳しく解説している教科書はほとんど見かけませんが、自分でちょっと試行錯誤すればすぐ使えるようになります。うまく使いこなせば、複雑な構造を持つスクリプトを非常に楽に組めるようになりますので、ぜひ挑戦してみて下さい。


Tipsに戻る
AppleScriptのページに戻る
このホームページに関するお問い合わせは、karino@drycarbon.comまで。