| ログイン | ご入会 |
ADC連絡先
|
|
| |
はじめにこのようなガイドラインが存在するのはなぜかこれらのガイドラインは、「Human Interface Guidelines」 と同様に、あらゆる Macintosh 用アプリケーションのスクリプティングインタフェースの基本的な設計原則と一貫性を促進することを目的としています。設計原則は、いかにタスク指向にするかというものです。つまり、アプリケーションをユーザの思考モデルに綿密に一致させるほど、便利なものになります。スクリプティングインタフェースの一貫性は、通常のインタフェースと同じ理由で有益です。ユーザが新しいアプリケーションを容易に習得することができ、従来の習慣に従うことで生じる間違いのリスクが低下するため、対応しなければならないサポートコールの数が減ります。さらに、アプリケーション間の一貫性により、AppleScript が、実質的に異なる言語の寄せ集めを結合する単なる薄い接着剤ではなく、緊密性の高い体系として推進されます。 これらのガイドラインに従うことで、ユーザを満足させ、自分自身を楽にし、AppleScript を便利なツールとして普及させることができます。 スクリプティングとはスクリプティングは、スクリプティング言語を使用するプログラミングです。
これではあまり参考になりませんね。スクリプティング言語とは何でしょうか。C、C++、または Java などのシステムプログラミング言語に対して、スクリプティング言語はタスク指向のプログラミング言語です。システムプログラミング言語は、アプリケーションをゼロから開発するために設計されており、非常に汎用的です。何でも作成できますが、多くの場合は非常に小さな要素からすべてのものを開発する必要があります。一方、スクリプティング言語は、特定のタスクを念頭に置いて設計されています。スクリプティング言語では、タスクに適したことを非常に簡単に表現できますが、他のことに関しては扱いにくかったり、 何もできないことさえあります。たとえば、 タスク指向であることは、いくつかの点で優れています。作成するコードが少なくて済むだけでなく、精通した範囲の内容であれば、人間のほうが(プログラミングのような)知的なタスクに優れています。そのため、ポインタやビット演算に戸惑う出版社でも、テキストフローやイラスト単位の処理を行う複雑なスクリプトを作成することができます。 何がタスク指向かを考える際には、何がタスクであるかだけでなく、何がタスクでないかを考えると分かりやすいでしょう。たとえば、前述の出版社はボックスの大きさやカーニングには関心がありますが、メモリ管理や変数型の宣言には関わりたくありません。したがって、スクリプティング言語はメモリの割り当てと割り当て解除を自動的に行い、変数の型を必要とせず、一般にシステムプログラミング言語では必要とされる多くの詳細の面倒を見てくれるという傾向があります。 このような重点化と便利さには、もちろん犠牲が伴います。問題によってはひどく不適切なスクリプティング言語もあり、スクリプティング言語で書かれたプログラムは一般に、システムプログラミング言語で書かれた同等のプログラムより動作が遅くなります。他方で、スクリプト作成者がシステムプログラミング言語を使用した高速なバージョンをまったく書けないかもしれませんし、単純に時間がないかもしれません。そして、書かれないプログラムの速度は、せいぜい人が手でタスクを実行する速度と同じです。 このテーマに関する補足的な見解については、John Ousterhout の論文「Scripting: Higher Level Programming for the 21st Century」を参照してください。 スクリプタビリティとはスクリプタビリティとは、キーボードやマウスを使った人の操作ではなく、スクリプト(つまり、プログラム)でアプリケーションをコントロールできる能力を指します。アプリケーションをスクリプト対応にすることで、ユーザはアプリケーションをカスタマイズし、自動化したワークフローに組み込み、多くの場合、特殊すぎて手間をかけることも考えなかったような方法や、そもそも想像さえしなかったような方法で役立てます。 スクリプタビリティに取り組む方法はいくつかありますが、最も興味深く、有益なのはアプリケーションのモデルレイヤを公開することです。この用語は、MVC(model-view-controller)のデザインパターンに由来するものです。モデルレイヤでは、アプリケーションデータとそれに作用するロジックを保持しています。ビューレイヤは、そのデータを目に見える形式で表示します。また、コントローラレイヤは両者を調整し、モデルの変更に応じてビューを更新したり、ユーザのビュー操作に応じてモデルを更新します。詳細な説明については、「The Model-View-Controller Design Pattern」を参照してください。 ビューではなく、モデルを公開することには、2 つの重要なメリットがあります。まず、モデルは一般に、ビューよりも安定しています。新バージョンのアプリケーションを作成するときには、ボタンを移動したり、コマンドを変更するかもしれませんが、アプリケーションで実質的に行うことは比較的一定しています。スクリプティングがモデルに基づいていれば、既存のスクリプトとスクリプト作成者の知識は有効なまま残ります。次に、モデルはタスクを実行する方法ではなく、タスクそのものを扱うので、より有益です。たとえば、Finder でファイルの名前を変更したい場合は、ビュー指向の手順(ファイルを選択し、名前の部分をクリックして、文字を入力する)を記述するのではなく、「当該ファイルの名前を設定せよ」と指示することができます。 AppleScript とはAppleScript はアップルが開発したスクリプティング言語で、スクリプト対応の Macintosh 用アプリケーションをコントロールするための基礎言語です。AppleScript は英語のような構文を持ち、高度にオブジェクト指向で、オブジェクトの大きな集合の取り扱いに特に適した機能をいくつか備えています。詳細については、「AppleScript Language Guide」を参照してください。 AppleScript は、タスク指向であるために独特のアプローチを採用しています。基礎となる言語はほとんど何もしませんし、タスク固有の機能もまったくありません。この言語が行うのは、タスク固有の機能(つまり、アプリケーション)をいくらでも組み込めるフレームワークを提供することです。対象となるオブジェクトに応じて、ボキャブラリ(語彙)が変化します。たとえば、Finder とやりとりするときは、ディスク、フォルダ、およびファイルについて指示できます。また、Mail とやりとりするときは、メッセージやメールボックスなどについて指示できます。言い換えると、アプリケーションが、知っているタスクに関するタスク固有の機能を提供する役割を担います。そして AppleScript が、アプリケーション間で情報をやりとりする基本的なインフラとグルーを提供します。 基礎アプリケーションのスクリプティングインタフェースは、用語説明によってシステムと人間のユーザの両方に対外的に公表されます。用語説明には、アプリケーションが理解するすべてのオブジェクトとコマンドに加えて、それらの関係やそれらの意味に関する簡単な説明が記載されています。AppleScript は用語説明を読み取ってスクリプトのコンパイル方法を判断します。また、アプリケーションでできることを知りたいスクリプト作成者が参照する基礎参考資料でもあります(基礎参考資料だけを提供すればよいというわけではありません。理想的には、文書やサンプルスクリプトも提供してください。ただし、用語説明は必須です)。 このセクションでは、用語説明を作成するための一般的なガイドラインについて説明します。後のセクションには、オブジェクトやコマンドなど、特定のトピックに関する個別の指針が含まれています。 最初に用語説明全体を作成してから実装するべきか、作成と実装を少しずつ反復作業で実装していくべきかについては、意見が分かれています。どちらにもメリットがあるので(前者は一貫性を持たせるのが容易ですし、後者はいつでも簡単に出荷できます)、どちらでも自分に適したほうを選んでください。 用語説明には現在、3 つの異なるフォーマットがあります。
ユーザの視点で用語説明を表示するには、スクリプトエディタで開きます。スクリプトエディタを起動し、「ファイル」メニューから「用語説明を開く」を選択して、アプリケーションを選択します。スクリプティングが初めての場合は、他の用語説明もいくつか見てください。Finder は良い参考になります。ガイドラインに十分に従っており、興味を引く程度に十分複雑で、理解できる程度に十分シンプルです。 ![]() 図 1. Finder の用語説明の一部 はじめる前に後ではなく、先にスクリプタビリティついて考える設計プロセスの初期にアプリケーションをスクリプト対応にする方法を考えておけば、かなりの時間と苦労を省けます。まず、機能を最後に取ってつけたように追加よりも、最初から計画していた機能を実装するほうが確実に簡単です。次に、さらに重要なのは、スクリプタビリティを考えれば、必然的にモデルについて考えることになるという点です。概念上のモデルオブジェクトが何であるか分かっていれば、それ一致する実装オブジェクトを作成することができます。これでスクリプタビリティが容易になるだけでなく、それは優れた設計手法でもあります。 モデルを理解するスクリプタビリティはタスク指向であることを意味し、タスク指向であることはアプリケーションが実行すること、つまりモデルを明らかにするということです。そのため、アプリケーションモデルを正確に把握することが不可欠です。アプリケーションが実行することを定義するオブジェクトとコマンドは何ですか。そして、それらはどのように互いに関連していますか。たとえば、Mail にはメールボックスがあり、メールボックスにはメッセージが収納され、メッセージには受信者とテキストがあり、送信や転送ができます。ボタン、メニューコマンド、またはダイアログについては何も言っていないことに注目してください。大切なのはモデルで、ビューではありません。 どのようなモデルあるか分からなかったり、モデルがないと思う場合は、おそらくアプリケーションの捉え方に誤りがあるか、アプリケーション設計を改善する必要があります。このような場合、ユーザと話をすると有益であることがあります。ユーザが何をするのか質問し、よく使用するオブジェクトとコマンドを聞きます。 ユーザを知るタスク指向であることは、プログラマのタスクではなく、ユーザのタスクに固有であるということです。アプリケーションについて、ユーザがそれで何を実行するのかを考えます。あなたが開発者として舞台裏で何かを行う方法に関してではありません。用語説明のオブジェクトやコマンドは、アプリケーションの平均的なユーザが一見してそれが何であるか分かるものにする必要があります。非常に大きくて複雑なアプリケーションの場合、ユーザを知ることは、最初にスクリプト対応にするものの優先順位を決める際の参考にもなります。一気にスクリプト対応にする必要はありません。 AppleScript を理解するAppleScript を詳細に学習する必要はありませんが、一般的なアプリケーションコマンドの構文、および AppleScript がしてくれること(したがって、自分でする必要のないこと)については感覚を養ってください。「AppleScript Language Guide」は AppleScript に関するアップルの公式文書ですが、サードパーティの書籍もいろいろ入手できます。ガイドラインに準拠したスクリプト対応アプリケーション(Finder など)を使ってみるのも、学習するには良い方法です。 アプリケーションフレームワークを使用するスクリプタビリティを適切に実装する作業の大部分は、標準的な振る舞いを実装する作業です。フレームワークを使用すると、骨の折れる仕事の多くがなくなり、間違いの数が減ります(あるいは少なくとも、フレームワークを使用している他の人たちと同じ間違いだけで済みます)。アップルの Cocoa と Metrowerks の PowerPlant はどちらも、スクリプタビリティに対して優れたサポート機能を提供しています。 用語説明の設計タスクにこだわるすでに述べたことではありますが、これは重要です。優れたスクリプタビリティは、ユーザにとって意味のあるタスクを中心に考えます。エラーコードやビットフィールドなど、ユーザが通常目にしないことを話している自分を発見したら、それはタスクから外れていっているということです。また、タスクがビュー(すなわち、どのように)ではなく、モデル(すなわち、何を)をベースにしていることを忘れないでください。ボタンやメニューについて話している(そして、インタフェース構築アプリケーションで作業していない)自分を発見したら、それはビューのスクリプトを作成しようとしているということです。一部のビュースのクリプティングは重要ですが(「ビューのスクリプティング」を参照)、それが中心ではありません。「タスク」について考えられなければ、代わりに、次の 2 つの指針を覚えておきましょう:プログラマではなく、ユーザと話をすること。そして、ビューではなく、モデルのスクリプトを作成すること。 ユーザが妥当と考えるような方法でモデルを表現できない場合、それはモデルの修正が必要であることを示しているのかもしれません (ひと休みする必要があることも示しているかもしれないので、ひと休みするのもよいでしょう)。このようなことはときどき起こります。別の角度からモデルを見ると、以前ははっきり見えなかった問題が明らかになることがあります。たとえば、1 つの複雑な操作を分割したり、2 つをマージしたりする必要があったり、タスクの分野を思ったほどよく理解していなかったというような原因が考えられます。とにかく先へ進んで問題を修正し、グラフィカルインタフェースでも問題を修正します。修正できれば、より良いアプリケーションになるでしょう。 オブジェクト指向であることオブジェクト指向であるということは、スクリプティングをコマンドではなく、主にオブジェクトを中心にして編成するということです。オブジェクトはコマンドに応答できますが(文書を印刷できる、メッセージを送信できるなど)、注目の対象はコマンドではなく、オブジェクトです。これには、いくつかのメリットがあります。 まず、AppleScript の他の部分、そしてある程度は Macintosh 全体としての動作の仕組みに適合しています。したがって、より一貫性があり、ユーザにも納得がいきます。 次に、開発者が 第三に、n 個のコマンドと m 個のオブジェクトを組み合わせると n×m 個のアクションになるという倍数効果のおかげで、n+m 個の用語だけで構成される小さくて分かりやすい用語説明を作成することができます。8 つのプロパティを持つ 的確であることサポートしているとする用語を、用語説明で確実にサポートするようにします。必要ならば、用語説明では慎重を期します。まだ出番の準備が整っていない感じられる用語については、sdef を使用して隠すことができます (古い 同様に、用語説明でプロパティとパラメータについて定義する型が的確であるようにしします。この場合の「的確」であるということは、実装者の観点ではなく、 スクリプト作成者(つまり、ユーザ)の観点から見て、ということです。たとえば、AppleScript には 「file URL」というタイプは存在しませんが、「file」というタイプは存在するため、 アプリケーションがパラメータを すでにあるものを作らない独自に考案したものが少ないほど、一貫性が高くなり、ユーザが学習しなければならないことも少なくて済みます。
その結果として、おそらく独自のコマンドをたくさん定義する必要はなくなります。標準コマンドは基本的なアプリケーション機能とオブジェクト操作を処理します( GUI 未満のことをしても大丈夫グラフィカルユーザインタフェースで可能な操作の中には、スクリプトだと実際的に不可能な動的な対話レベルを前提にしているため(たとえば、フリーハンドのスケッチやムービーの修正など)、スクリプティングインタフェースに適していないものもあります。グラフィカルインタフェースに存在するというだけで、スクリプティングインタフェースに機能を盛り込む義務があると思う必要はありません。 また、アプリケーションのすべてを一度にスクリプト対応にするのも現実的でない場合もあります。時間がない、次期リリースで機能が変わる、などさまざまな理由が考えられます。提供できるものを提供し、役立つものにして、残りは後で取り組みます。 GUI 以上のことをしても大丈夫スクリプタビリティは、グラフィカルユーザインタフェースを実装せずにアプリケーションの機能を公開できる素晴らしい手段です。中には、AppleScript の仕組みに潜んでいる機能もあります。たとえば、Finder には特定の条件を満たすファイルを削除するコマンドはありませんが、 フィードバックを得るスクリプティングに関心があるユーザを何人か見つけ、アプリケーションを使わせて、意見を聞きます。すでにそうしたユーザがスタッフにいる場合もあります。たとえば、テスターは仕事が楽になるので、スクリプティングを好む傾向があります。 完了したらテスト、テスト、とにかくテストスクリプタビリティも、他の機能と同様にテストする必要があります。ここでは AppleScript に関する知識が非常に役立ちます。スクリプトを作成できるだけでなく、この言語を徹底的に使うことができるからです。初心者はしばしばオブジェクト指定子の意味合いをつかめずに、範囲またはフィルタ節が使用できないコマンドを作成します。 さらにフィードバックを得る内部の開発とテストも結構ですが、何ものも現実世界における利用の代用にはなりません。実際のユーザにスクリプト対応アプリケーションを試用させましょう。出荷した後でスクリプタビリティに間違いが見つかっても、同義語を利用すれば、既存のスクリプトを壊すことなく変更を加えることができます。詳細については、sdef の man ページを参照してください。 スタイルこのセクションでは、用語説明のスタイルガイドライン(構成、名前の付け方、コメントスタイルなど)について説明します。 全般必要に応じてスイートを使用する用語説明はスイートに分かれていますが、これは互いに関連のあるクラスとコマンドのかたまりです。これらは純粋に読者の便宜のためであって、アプリケーションや AppleScript にはまったく影響を与えません。スイートを構成する項目の数に関しては技術的な上限や下限はありませんが、10〜15 が快適なサイズだと考えられています。ただし、大きなスイートを分割したり、小さいスイートを結合することだけを目的として、無理やり不自然な分け方をしないでください。最も重要なポイントは、ユーザが目的のものを探しやすいようにすることです。 システム定義のスイートを先に置き、独自スイートはその後に置きます。それらを一般性や使用頻度の順に並べ、それが駄目な場合はアルファベット順に並べます。 スイート内およびクラスのプロパティは、何らかの実用に適した順番に項目を整理します。グループが十分に小さければ、重要性や使用頻度の順に並べられますが、これは判断が難しい場合があります。アルファベット順に並べるのは、いつでも便利な最後の手段です。 コマンド内では、文の中で意味を成すようにパラメータを並べます。これが不可能な場合は、アルファベット順を使用します。 型が的確であることプロパティやパラメータの型を指定する際は、ユーザにとって的確で意味のある最も明確な型を使用します。多くの場合、これはアプリケーションで定義した単独のクラスやプリミティブなデータ型の単純な選択ですが、ときどき趣が異なることもあります。
オブジェクトを参照するものはオブジェクトにするプロパティやパラメータがオブジェクトを参照する場合、その型も実際のオブジェクトにします。決して、オブジェクトを示すデータにしないでください。多数の Web ブラウザに存在する、このガイドライン(および他のいくつかガイドライン)に違反する次のコマンドを考えて見ましょう。 CloseWindow これを行う正しい方法は、 ファイルに関する一言 言語要素の選択プロパティと要素オブジェクトは他のオブジェクトを含むことができます。これらは、名前付きプロパティ( プロパティとコマンドときどき、プロパティを設定すると、画面にすぐに変化が起こる場合があります。このような状況でプロパティを使用するべきかどうか判断する際には、次のルールが役に立ちます。何らかのアクションが開始されるようならコマンドを使用し、属性が変化するようなら(その変化がすぐに視覚的な結果をもたらす場合でも)プロパティを使用します。別の角度から見て、次のようにも考えられます。視覚的な変化がただちに起こる場合はプロパティを使用し、アクションに持続時間がある場合はコマンドを使用します。 たとえば、次のコマンドは画面上でただちに変化を引き起こします。 set the font of the third paragraph to "Courier" フォントプロパティを設定すると、視覚的な変化が引き起こされますが、フォントは依然としてテキストの属性であり、アクションではありません。他方で、次の 2 つのコマンドで示すように、プロパティまたは列挙子に set playing to true set [the] status to playing 2 番目のコマンドにある play the movie "Wowie Zowie" start playing the movie "Wowie Zowie" ここで留意すべきは、コマンドが 列挙列挙は、固定の選択肢のセットを表す定数(列挙子) のセットです。特定の選択肢で構成されるリストから選択させる場合には、パラメータまたはプロパティの型として列挙を使用します。これは、ユーザが選択肢の存在を知るのに役立ち、それらの選択肢が何であるかを正確に知ってもらうことができます。
命名規則ユーザ側の用語を使用し、実装側の用語を使用しないユーザと話をするのだから、ユーザになじみのある用語を使用することを忘れないでください。理想的には、グラフィカルインタフェース、スクリプティング、および文書で使用する用語はすべて一致させるべきです。 「the」 テストの利用AppleScript では、スクリプトの意味を変えることなく set the service to "America Online" if the priority is high then ...
小文字を使用する固有名詞、商号、頭字語に必要な場合を除き、用語にはすべて小文字を使用します。
複数の語をそのまま連結したり、アンダーバーで連結したりしない用語が複数の語で構成されている場合は、語をスペースで区切ります。大文字やアンダースコアで語を連結しないでください。この場合も、商号は例外です。
用語は AppleScript 識別子ルールに準拠すること用語の各語は有効な AppleScript 識別子でなければなりません。つまり、各語は英字またはアンダーバーで始まり、その後に任意の数の英字、数字、またはアンダーバーが続く必要があります。C 言語系の言語と同じです。句読点は使用できません。前述のように、アンダーバーはお勧めしません。 オブジェクトのように見えるコマンドや、コマンドのように見えるオブジェクトは作成しない他の品詞のように見える用語を作成すると、スクリプト作成者が混乱し、動作しない処理を試みるかもしれません。標準の追加コマンドの プロパティ名の先頭に命令法の動詞を置かないプロパティ名の先頭に動詞を置くと、プロパティが文の中ほどに出現した場合に混乱を招きます。たとえば、プロパティを set disable call waiting to true if disable call waiting then ... また、「disable call waiting」 という名前はコマンドのように見えます。ユーザは次のように書きたくなるかもしれません、 disable call waiting これをコンパイルして実行することは可能ですが、何も無効にしません。単に、プロパティの現在値を返すだけです。このような混乱は、代わりに分詞を使用して防ぐことができます。このほうがいくぶん明確になります。 set call waiting enabled to false if not call waiting enabled ... さらに良い方法は、プロパティを set call waiting to enabled if call waiting is disabled ... 用語の先頭に言語のキーワードを置かない用語で最初の語として言語のキーワードを使用すると、文脈によってはそのキーワードを使えなくなる可能性があります。たとえば、 用語の先頭にキーワードをうまく置くことは可能ですが(標準の追加コマンドの AppleScript 1 の予約語は以下のとおりです。
Boolean 型のプロパティとパラメータ名に
|
| 悪い例 | begin animating, end animating |
| 良い例 | start animating, stop animating |
用語説明の用語は、関連するコメント(sdef およびスイートでは description 属性、または aete のコメントフィールド)を持つことができます。これらを利用して、ボキャブラリの使い方を明確に示すことができます。用語説明は多くの場合、何ができるかをユーザが知るのに最初に調べる「ウインドウ」であるため、分かりやすいコメントであれば、ユーザの作業が大いに楽になります。ユーザは必ずしもプログラマではないので、コメントの中では実装側の用語の使用を避けてください。
Boolean パラメータおよびプロパティについて、2 つの状態が考えられる場合は、「true if the script will modify the original images, false if the images will be left alone:スクリプトが元のイメージを変更する場合には true、イメージがそのままの状態で残る場合は false」のように、true と false の条件に関する説明を盛り込みます。
オンとオフの状態が考えられる場合は、true 条件(「If true, then screen refresh is turned on」:true の場合、画面のリフレッシュはオン)だけを含めるか、「is」 または「does」で始まる質問(「Is the window zoomed?」:対象ウインドウはズームされているか?)をするだけで済みます。
列挙型のパラメータまたはプロパティについては、それが表す対象の一般説明を含めます。個々の列挙子は一目瞭然であるべきです。たとえば、次のように記述します。「yes | no | ask -- Specifies whether or not changes should be saved before closing:閉じる前に変更を保存するかどうかを指定します。」
列挙(と分かりやすい列挙子)のほうがよい場合は、考えられる数値のセットを説明するためにコメントフィールドを使用しないでください。たとえば、 「0=read, 1=unread, …」ではなく、 「read | unread | …」を使用します。
複数の型を許可する場合は(sdef の type="T1 | T2 | ..." を参照)、リストに示した型の選択肢に関する次のような説明を含めます。「the connection’s window (either a reference or name can be used):接続のウインドウ(参照または名前を使用できます)。」
パラメータまたはプロパティにデフォルト値(ユーザが省略可能パラメータを省略したり、プロパティを設定しなかった場合に使用されます)がある場合には、それについて言及します。これはどんな型の値にも適用されます。たとえば、「replacing yes | no | ask -- Replace the file if it exists? (defaults to ask):ファイルがあれば置き換えますか?(デフォルトは ask)」。
AppleScript は非常にオブジェクト中心であるため、目的に合ったオブジェクトとクラス階層を定義して、あらゆる標準の動作をさせることがおそらく、アプリケーション用に優れたスクリプティングインタフェースを作成する最も重要な部分です。Fred Brooks の言葉を若干言い換えて引用します。「コードを見せられても、オブジェクトを隠されていては、当惑し続けるだけでしょう。オブジェクトを見せてもらえば、たいていコードは必要ありません。一目瞭然ですから。」
いつものように、基本的なルールはタスク指向であることです。ユーザがアプリケーションで実行することに直接関連するオブジェクトを明らかにします。インタフェースではなく、モデルを公開します。実装の詳細は公開しないことです。ユーザは気にすることもないし、悪ければ、混乱に陥るだけです。
考慮すべき 2 つの階層があります。つまり、継承階層(何が何に似た動作をするか)と包含階層(誰が何を所有しているか)です。階層がユーザの予期する内容に合うようにしてください。
AppleScript は単一継承をサポートしているため、特定のクラスに似た、プロパティや要素を追加したクラスを定義することができます。サブクラスでは、必ずしも新しいパーツを定義する必要がありません。時には、異なるクラスであるだけで十分です。Mail の recipient クラスは、そのような継承を行っています。
継承を使用すれば、冗長な情報を削除することで、用語説明を効率的に縮小できます。複数のクラスが共通の要素やプロパティを持っている場合は、共通のパーツを定義する基底クラスからすべてのクラスを継承するようにします。クラスに子孫が 1 つしかない場合は、用語説明が複雑になるだけなので、継承は使用しないようにします。
AppleScript では、要素とプロパティの 2 種類の包含関係が定義されています。実体関連モデリングの言葉で説明すると、要素は対多関係で、プロパティは属性または対 1 関係です (実体関連モデリングではプリミティブデータと他のオブジェクトを区別しますが、AppleScript では区別しません)。プロパティは単一値ですが、要素はいくつでも存在できます。「0 または 1」あるいは「一定範囲の任意の数」のような特別な場合は、以下に示すように、プロパティまたは要素を使用し、振る舞いを追加してエミュレートすることができます。
| 数量 | 使用項目 | 例 |
| 1 つのみ | プロパティ | 名前 |
| 任意の数 | 要素 | 書類 |
| ゼロまたは 1 | プロパティ。値は missing value も可 |
カレント プリンタ |
| n。ただし n > 1 | 要素。ただし、make も delete できない |
"System Events" アプリケーションのドメイン |
一般に、値がオブジェクトのリストであるプロパティより要素を選ぶようにします。要素のほうが一貫していて、実装が簡単だからです。特に、次のようなことはしないでください。
class widget (pl. widgets)...
class box:
property widgets: list of widget
これは実際は違うのに、widget が box の要素に見えるので厄介です。たとえば、widgets of box 1 は動作し、「every」 指定子のように見えますが、実際にはプロパティ指定子であるため、同等と考えられる every widget of box 1 は機能しません。
このようなプロパティ(たとえば、標準の selection プロパティを参照)を実装する場合は、オブジェクト指定子内で通常のコンテナとまったく同じように機能するようにします。要素サブクラス、フィルタなどですべて正しく機能する必要があります。
application ルートオブジェクトは別として、アプリケーションのオブジェクトはすべて、他のオブジェクトに包含されています。特定オブジェクトまたはオブジェクトのセットを選択するために、スクリプトではオブジェクト指定子(略して、指定子)を使用します。オブジェクト指定子は、オブジェクト-式 of コンテナの形式で表記されます。コンテナ自体がオブジェクト指定子であるため、アプリケーションは包含の連鎖を再帰的に遡り、(たいてい暗黙の)ルートオブジェクト application(これがすべてを包含する)に達します。たとえば、次のようになります。
length of word 1 of every paragraph of document "Smith Project"
下線部分は各コンポーネントを示します。各コンポーネントが異なるキー形式を使用している点に注目してください。全キー形式を次の表にリストアップします。ほとんどのキー形式は、当該オブジェクトに特定プロパティが存在することを前提としています。オブジェクトに当該プロパティがあれば、対応するキー形式をサポートする必要があり、その逆もまた同様です。
| キー形式 | 前提プロパティ | 例 |
| 任意 | — | some file of the startup disk |
| every | index | every word of document 1 |
| フィルタ | — | every document whose name starts with "Smith" |
| ID | id | application file id "com.apple.finder" |
| インデックス | index | word 3 |
| middle | index | middle shape of drawing 1 |
| 名前 | name | folder "Bob" |
| プロパティ | — | name of document 1 |
| 範囲 | index | words 3 through 8 |
| 相対 | index | word after word 4 |
さらに、コンテナに許されるキー形式はコンテナの性質とその要素によって決まります。これによって、該当する場合には、どの場所が make および move コマンドにとって意味があるかも決まります。大雑把に言って、3 種類のコンテナがあります。
ordered(順序付き)コンテナでは、項目をどのように配置するかをユーザが厳密に決定します。どんな項目も、make または move を使用して、他の任意の項目の前(または後)に置くことができ、置いたらそこに留まります。テキスト書類の段落および AppleScript リストの項目は順序付けられています。
unordered(順序なし)コンテナでは、項目の順序がデータ自体によって決まるか(アルファベット順など)、単純に特定の順序がありません。n 番目の項目を要求したり、すべての項目を反復処理したり、項目の前後にある別の項目を指定することは可能ですが、特定の位置に項目を作成したり、その位置に移動するよう要求しても意味がありません。できるのは、項目をコンテナに入れるように要求することだけです。アドレスブック内の人、Finder 内のファイル、および AppleScript レコード内の項目はすべて順序付けられていません。
uncounted(数えられない)コンテナでは、アプリケーションはいくつの項目があるのか分かりません。あらゆるインデックス形式にも、every という考え方にも意味はありません。項目を取得するには、名前、ID、何らかのプロパティなど、当該項目について何か別のことを知っている必要があります。インターネット上の Web サーバは数えられません。
| コンテナのタイプ | 例 | アクセス方式 | make 先 |
| ordered | AppleScript リスト | インデックス、相対、任意 | インデックス、相対、コンテナ |
| unordered | AppleScript レコード、 アドレスブック内の人 |
インデックス、相対、任意 | コンテナ |
| uncounted | インターネット上のすべての Web サーバ | — | コンテナ |
このセクションでは、各キー形式の動作を詳しく説明します。構文や使い方の詳細を提供するものではありません。それらについては、AppleScript Language Guide の Chapter 5 を参照してください。
このキー形式をサポートする場合には、常に同じものは返さずに、純粋にランダムにオブジェクトを返すようにします。このキー形式は、スクリプトがランダムな動作を必要とする場合に役立ちます。たとえば、スクリプトで複雑な signature (random number from 1 to (count signatures)) ではなく、 some signature と記述すれば、Mail でランダムな署名を選択することができます。
every item は、every が要素のない場合にエラーではなく、空のリストを返すことを除けば、items 1 through -1 と同等です。詳細については 「範囲」 を参照してください。
filter はインデックスベースのキー形式(インデックス、任意、middle、範囲、および、every)に対する修飾子と考えたほうが正確ですが、歴史的な経緯から、独自のキー形式と考えられています。フィルタキー形式はオブジェクのプロパティに対するテスト(files whose name contains "Smith" のように)で最もよく使用されますが、要素またはオブジェクト自体を対象としたテストも可能です。たとえば、次のようになります。
paragraphs where it starts with "The" albums where it contains photo "White Rabbit" documents whose first paragraph contains the word "Metacortex"
理論上は、任意のブール式も有効であるはずですが、AppleScript は現在、フィルタ式における関数呼出しを処理できません。
対象オブジェクトの属性がフィルタで指定されていなくても、エラーではありません。その場合には、値を missing value であると考え、適切に対処するようにします。
id プロパティが指定の値に一致する単一オブジェクトを返します。ID データは、considering caseなど、現在の AppleScript の条件に従うべきではありません。ID は、一貫して大文字 / 小文字を区別しないようにするか、区別が重要な場合には一貫して区別する(つまり、"ijkl" と "IJKL" はともに有効で、異なる)ようにします。
項目インデックスは、最初(first)から最後(last)または先頭(front)から末尾(back)の順序付けに関するユーザのモデルと一致しなければなりません (実際、AppleScript では first と front は同義語で、last と back も同様です)。つまり、window 1 は必ず最前面ウインドウであり、table 1 は書類の中で最初の表であるということです。負のインデックスは末尾から逆方向に進むので、item -1 と last item は同じことを意味し、item -2 は最後から 2 番目になります。
項目が上で定義したように順序付けられていない場合、理想的には、インデックスは項目が現在表示されている順序に一致しなければなりません。それが可能でなければ、一貫性のある順序(たとえば、アルファベット順)を採用し、それを使用します。
name プロパティが指定の文字列に一致する単一オブジェクトを返します。文字列の照合では、considering case や ignoring diacriticals など、現在の AppleScript の条件に従う必要があります。名前データは、プレーンテキストまたは Unicode テキストとしてアプリケーションに渡される可能性があるので、内部処理で完全な Unicode を使用していなくても、どちらにも対応する準備ができているようにします。
範囲は、2 つのインデックスまたは 2 つのエンドポイントオブジェクト(これらは範囲に含まれる)のいずれかとして指定することができます。どちらか一方のエンドポイントが存在していないか、両方が同じコンテナ内にない場合は、エラーを返すようにします。上記のインデックスキー形式の場合のインデックスの意味に関するガイドラインが適用されます。
エンドポイントの順番は重要ではありません。必ず最小インデックスから最大インデックスの順番でオブジェクトを返すようにしてください。たとえば、words 8 through 1 は words 1 through 8 と同じ内容を返さなければなりません。
テキストの場合は特別な扱いとなります。包含の仕組みに起因して、一方が他方の内部にある 2 つのエンドポイントを指定することができます (通常なら、両オブジェクトはコンテナが異なることになるので範囲は無効です)。これを解決するには、両方のエンドポイントの先頭を探し、テキストの先頭に近いほうのエンドポイントから開始し、次に他方のエンドポイントオブジェクトの末尾に移動します。たとえば、次のようになります。
set t to "Through three cheese trees three free fleas flew" words from paragraph 1 to word 3 of t --> {"Through", "three", "cheese"} characters from character 10 to word 2 of t --> {"h", "r", "e", "e"}
範囲指定子は、その範囲のオブジェクトが 1 だけの場合でも(あるいは、「every」 の場合はオブジェクトがなくても)リストを返します。範囲参照を別のプロパティまたはオブジェクトのコンテナとして使用すると、その結果は範囲内にあるすべての項目の当該プロパティまたはオブジェクトになります。たとえば、次のようになります。
name of files 2 thru 3 of home --> {"Memory report", "BBEdit update.dmg"}
値のリストを返すときは、その範囲について返されるリストと必ず同じになるようにします。つまり、同じ順番で、同じ数の値を返すようにします。たとえば、次のようになります。
every duck --> {mallard "Daffy", pintail "Marvin", decoy duck "Q-36"} name of every duck --> {"Daffy", "Marvin", "Q-36"}
これは、オブジェクトの一部が、指定されたプロパティや要素を持っていなくても適用されます。そのようなオブジェクトの場合は、missing value を返します。先ほどの例を続けて、「feet are webbed」 プロパティを考えてみましょう。おとりのカモ(decoy duck)には足がないとします。
feet are webbed of every duck --> {true, true, missing value}
指定した要素が別の範囲である場合は、その結果はリストのリストになります。たとえば、次のようになります。
every duck of every flock --> {{mallard "Ned", mallard "Ted"}, {pintail "Ann", pintail "Dan"}}
相対指定子は、クラス (before | after) 指定子 という形式です。ただし、指定子 には、別の相対指定子を含め、任意の指定子を指定できます。したがって、word after word after word 1 は、3 番目の語を記述するまったく有効な方法です。奇異に見えるかもしれませんが、テキスト選択の処理にとっては重要です。選択が、insertion point after word 12 のような挿入ポイントの場合、そのポイント後の語は word after insertion point after word 12 となります。
コンテナは、それが保持するあらゆるクラスの要素関係を個別に定義する必要はありません。それらを継承で示すことができます。オブジェクトに何らかのクラスのオブジェクトが含まれている場合、指定子を使用して任意のサブクラスを指定すれば、要求は当該クラスのオブジェクトに限定されます。たとえば、DuckTracker という架空のアプリケーション考えてみます。
class duck: …
class canvasback: inherits from duck …
class mallard: inherits from duck …
class pintail: inherits from duck …
class application
element duck by index, by name…
ここでは、duck のみを要素として明示的に指定していますが、スクリプトで every mallard を要求し、すべての mallard(マガモ)に関するリストを受け取ることができます。
アプリケーションのオブジェクトは一般的に、いくつかの方法のいずれかを使用して参照することができます。たとえば、window 1、window "Lister"、および window id 743 はすべて同じウインドウを参照しているということがあり得ます。しかし、オブジェクトを返す必要がある場合(たとえば、スクリプトで名前が "L" で始まる最初のウインドウを取得するように要求する場合など)、特定のキー形式を選ぶ必要があります。選ぶ形式は正規オブジェクト指定子と呼ばれており、対象オブジェクトを参照するための最も信頼できる方法でなければなりません。つまり、物事が変化した後でも同じオブジェクトを参照する可能性が最も高い方法です。
使用する形式の原則は次のとおりです。
id プロパティがある場合は、それを使用する(window id 743)name プロパティがある場合は、それを使用する(window "Lister")window 1)。インデックスは必ず正の数にするオブジェクト指定子のクラスは、オブジェクトの実際のクラスでなければなりません。先の DuckTracker の例で考えると、これは duck id 8237 ではなく、mallard id 8237 のようになりますが、どちらも同じオブジェクトを参照します。
ほとんどのアプリケーションでは、オブジェクトの関係はすべて一対一または一対多であるため、どのオブジェクトも必ず別の 1 つのオブジェクトに包含されます。しかし、アプリケーションによっては多対一または多対多の関係があるため、1 つのオブジェクトが複数の異なるコンテナに出現することがあります。iPhoto は次のように振舞います。photo オブジェクトは、任意の数の album に含めることができます。このようなモデルは何も間違いはありませんが、一部調整を必要とします。
まず、add および remove コマンドをサポートする必要があります。これらのコマンドは、包含を操作するためだけに設計されたもので、make と delete のようにオブジェクトの作成と破棄を行うものではありません。make と delete には一部の作業に対しては適切な意味を表さないので、この区別は重要です。たとえば、既存の写真を iPhoto のアルバムに追加したいとしましょう。何かを作成するわけではないので、make は実のところ適切ではありません。同様に、アルバムから写真を取り除きたいとしましょう。delete は、写真をアルバムから取り除くだけなのか、それとも写真そのものを完全に削除するのか曖昧です。この問題をいろいろなコマンドなしで解決するには、「photo reference」 オブジェクトを導入します。しかし、そのようなものはユーザのモデルにはないので、「タスクにこだわる」というガイドラインに違反することになります。
次に、オブジェクト(iPhoto の例を続けて 「photo」 と呼びましょう)がどのコンテナ(「album」)にも属さないことがあるか検討します。たとえば、iPhotoで、どの album にも含まれていない写真(photo)が考えられます。このような場合には、すべての 「photo」 を保持する 1 つのマスタコンテナを指定する必要があります。そのコンテナから写真を 「album」 に追加したり取り除いたりすることになります (iPhoto では、マスタコンテナとして application を使用しています)。オブジェクトが必ずコンテナに属するのならば、マスタコンテナは必要ありませんが、たとえば最後の 「album」 から 「photo」 を削除するときは、それ自体を削除する必要があります。
一般に、特定のプロパティを使用してオブジェクトを取得した場合には、オブジェクトのプロパティは一致するはずです。たとえば、name of thing "Bob" は必ず "Bob" になり、id of thing id 427 は 427 になります。
しかし、アプリケーションによって、このようにならない場合もあります。通常その理由は、オブジェクトに複数の有効な名前(または id など)があることです。たとえば、Finder の application file クラスは、従来のクリエータタイプの id または新しいバンドル id に対応します。application file id "emal" と application file id "com.apple.mail" はどちらも同じものを返します。
複数のキーデータが同じオブジェクトを返しても、まったく問題ありません (これが曖昧さを生み出す場合は、以下を参照してください)。ただし、オブジェクトの指定に使用できる各種データをユーザが知るための何らかの手段を提供する必要があります。基本プロパティ(たとえば、name)は正規データを反映するようにします。残りについては、他のプロパティを追加します。たとえば、Finder でファイルの拡張子が非表示になっている場合、ファイルは表示名(拡張子なし)またはディスク上の名前(拡張子あり)のどちらかに応答します。ディスク上の名前は正規名とみなされ、表示名は displayed name プロパティで知ることができます。
通常、少なくともコンテナ内では名前と ID は一意であるため、folder "Bob" で返せるオブジェクトは 1 つだけです。しかし、必ずしもこのような場合だけではありません。たとえば、アプリケーションによっては、名前は純粋にユーザの参照用であって、一意性がまったく保証されないことがあります。
そのようなアプリケーションについては、「戻り型が一致していること」」ルールを思い出してください。名前とインデックスのキー形式は通常、単一オブジェクトを返すので、曖昧なオブジェクトの場合にも同様にする必要があります。あるオブジェクトが別のオブジェクトよりも的確に一致する場合は、前者を返します。一致する最適なものがなければ、最初のオブジェクトを返します。ただし、ユーザが何らかのフィルタ式(every item whose name is ... など)を使用して、一致するすべてのオブジェクトを選択できるようにする必要があります。
アプリケーションで定義すべき標準クラスがいくつかあります。アプリケーションで必ず定義する必要のある唯一のクラスは、包含階層のルートである application です (継承階層のルートである item は、AppleScript 自体で定義されているため、用語説明に含める必要はありません)。ここに示すプロパティは出発点にすぎません。ここに示すものはほとんど何もしないので、実際のアプリケーションではもっと多くのを定義する必要があります。クラスとプロパティは、アプリケーションにとって関連性がなければ省略することができます。たとえば、すべてのアプリケーションに書類やセレクションがあるわけではありません。同様に、ここで読み取り専用として示したプロパティは、アプリケーションによっては書き込み可能(あるいはその逆)であるかもしれません。
name テキスト [r/o] -- アプリケーションの名前。
frontmost 論理値 -- アプリケーションは最前面に表示されているか。
version テキスト [r/o] -- アプリケーションの短縮バージョン文字列。
selection 任意 -- 現在のセレクション。実際の型はアプリケーションによる。
element window
element document
application は包含階層のルートです。つまり、これには直接的または間接的に、アプリケーションに属するすべてのオブジェクトが含まれています。window 要素は、アプリケーションウインドウのうち、書類ウインドウなど他のスクリプト対応オブジェクトを含むウインドウだけです。モーダルダイアログ、シート、書式(ツール)パレットは含まれません (ただし、パレットはプロパティとして含むことができます)。
name テキスト [r/o] -- 書類の名前。
modified 論理値 [r/o] -- 書類に未保存の変更はあるか。
file ファイル [r/o] -- 書類のファイル。保存されたことがなければ missing value となる。
アプリケーション書類。name プロパティは、表示名で、ディスク上の名前ではありません。name および file は一般的に読み取り専用です。これらを変更するには、save コマンドを使用します。
name テキスト [r/o] -- ウインドウのタイトル。
bounds 矩形 -- ウインドウの境界矩形。
closeable 論理値 [r/o] -- ウインドウを閉じることが可能か。
minimizable 論理値 [r/o] -- ウインドウを最小化することが可能か。
minimized 論理値 -- ウインドウは最小化されているか。
resizable 論理値 [r/o] -- ウインドウのサイズ変更は可能か。
visible 論理値 -- ウインドウは可視か。
zoomable 論理値 [r/o] -- ウインドウは拡大表示可能か。
zoomed 論理値 -- ウインドウは拡大表示されているか。
書類ウインドウまたはパレット。シートまたはモーダルダイアログは含まれません。bounds は 4 つの数のリスト {top, left, bottom, right} として指定します。ディスプレイの左上が原点で、右方向および下方向に向かって x, y の値がそれぞれ増加します (つまり、Quickdraw 長方形です。AppleScript Studio はこれと異なり、bounds を {left, bottom, right, top} として返し、左下が原点で、右方向および上方向に向かって x, y の値が増加します)。visible は、ウインドウがほとんどスクリーン外に移動したかどうかではなく、表示/非表示コマンドのようにウインドウが可視の状態かどうかを指します。
class クラス [r/o] -- オブジェクトのクラス。
properties レコー -- オブジェクトの全プロパティ。
継承階層のルートで、すべてのクラスの最終的の祖先。class プロパティおよび properties プロパティの詳細については、後述を参照してください。item は AppleScript で定義されているので、用語説明に含めるべきではありません。特に、プロパティや要素を追加して item を再定義してはなりません。その場合には、独自のクラスを異なる名前で作成してください。クラスでは、item から継承することを明示的に定義する必要はありません。他の親がなければ、item が親であるとみなされます。
オブジェクトのクラス。これは必ず具象クラスであり、スーパークラスではなく、必ず読み取り専用です。class は、すべてのクラスの最終的な祖先である item で定義されているので、用語説明で明示的に定義する必要はありません。
包含階層内のオブジェクトは、当該オブジェクトを包含するオブジェクトを指すコンテナプロパティを定義できます (このプロパティは、たいてい実装するのが難しいため、完全に任意です)。正確な名前は、考えられるコンテナクラスによって決まります。ちょうど 1 つだけであれば、このプロパティにクラスと同じ名前を付けます。たとえば、Mail のメッセージは必ずメールボックスに属しているため、mailbox プロパティを持っています。複数の場合が考えられる場合は、総称の container を使用します。たとえば、Finder のファイルは、フォルダまたはディスクのどちらにも属することが可能です。parent という用語は使わないでください。これは継承階層でオブジェクトの直近の祖先を指します。
container プロパティは読み取り専用です。オブジェクトを移動するために container プロパティに書き込むことはお勧めしません。代わりに、move コマンドを使用してください。
多対 x 関係のオブジェクトには、意味のある単一のコンテナがないかもしれません。このようなオブジェクトでは、このプロパティを省略するべきですが、containers where it contains object 形式の指定子を必ずサポートしてください。
オブジェクトの内容を 1 つの値で表せる場合は、contents プロパティを定義する必要があります。たとえば、ワープロ書類では、すべてのテキストを文字列として返す contents プロパティを定義します。contents は通常、書き込み可能です。
再帰的コンテナ(つまり、要素として独自のクラスを持っているオブジェクト)は、entire contents プロパティを定義する必要があります。このプロパティは、すべての下位要素を含むフラットリストを返します。entire contents 自体は必ず読み取り専用ですが、その要素は書き込み可能な場合があります。
オブジェクトを一意に識別する値。ID は決してローカライズされず、一般的にユーザの管理下にないため、読み取り専用です。ID は少なくともコンテナ内では一意であるべきで(ほとんどのアプリケーションでは、アプリケーション全体の中で一意です)、少なくともアプリケーションプロセスまたはオブジェクトのどちらかが終了するまでは有効である必要があります。
値の型は何でもかまいません。一般的な選択肢は整数、UUID、またはバンドル識別子です。クラスの値の型は必ず一貫して同じでなければなりません。
オブジェクトの name プロパティはその表示名であり、システム識別子ではありません (アプリケーションによっては、表示名に関して若干柔軟な考え方を採用しているものもあります。前述の「非対称の指定子」を参照)。name は通常、書き込み可能ですが、一部のアプリケーションでは読み取り専用の場合もあります。
オブジェクトはすべて、properties プロパティがなければなりません。このプロパティは、オブジェクトのすべてのプロパティを含むレコードを返します。properties は、すべてのクラスの最終的な祖先である item で定義されているので、用語説明で明示的に定義する必要はありません。いずれかのプロパティが書き込み可能な場合は、properties も書き込み可能となり、当該オブジェクトのプロパティを任意の数だけ含むレコードを受け入れることができます。たとえば、次のように記述します。
get the properties of paragraph 4 -- フォント、サイズ、スタイル、その他を返す。 set the properties of paragraph 4 to {font:"Helvetica", size:14} -- フォントとサイズのみを設定する。
properties プロパティには、オブジェクトのすべてのプロパティ含める必要はありません。一般的に、リストの reverse プロパティのように、他のプロパティから得られるプロパティは含まれません。
AppleScript のコマンドは、オブジェクトとは独立に定義されます。そして、コマンドが定義されたら、クラスはどのコマンドに応答するかをリストアップできます。したがって、Java および Objective-C プログラマにとっては、コマンドはメンバ関数というよりは、プロトコルに似ています。現在のところ、クラスのコマンドを個別に(たとえば、異なるパラメータを持つように)定義する簡単な方法はありません。せいぜいできるのは、考えられるパラメータをすべてリストアップし、コメントを使ってどのパラメータがどういう場合に意味があるかを記述するか、コマンドを異なる名前で別々に定義することです。
AppleScript コマンドは通常、英語の命令文のように見えます。
動詞 [名詞] [前置詞 値]... save the front document in file "Goofballs:Razor"
自分のコマンドでも、このスタイルを真似るようにしてください。ただし、これはあくまでもガイドラインです。英語スタイルが完璧である必要はありません。また、考えられる英文をすべてサポートする義務は決してありません。同義語は理にかなっていれば問題ありませんが、度を超さないようにしましょう。
標準コマンドが使用できる状況なら使用するようにします。そして独自にカスタムコマンドを作成するのは、必要性が明らかに認められる場合に限定します。たとえば、Mail の 「send」 アクションは標準コマンドを使用する状況には当てはまらないので、独自のコマンドを作成することになります。他方、Finder ではオブジェクトの name プロパティの値を設定するだけのことなので、rename コマンドを定義していません。
every はリストを返す一般に、結果を返すコマンドは、ダイレクトパラメータ指定子と同じ「形」の結果を返さなければなりません。つまり、単数指定子は値そのもの、範囲と every 指定子はリストを返します (これには例外があります。count と exists を参照)。範囲の一端または両端が存在しない範囲指定子はエラーになりますが、オブジェクトを指定していない every 指定子はエラーになりません。このルールは、フィルタ処理した範囲指定子および every 指定子にも適用されます。たとえば、次のようになります。
-- インデックスのような単数指定子は値を返す。 get name of person 1 --> "Fillmore" -- 範囲と "every" 指定子はリストを返す... get name of every person --> {"Fillmore", "Poppleton"} -- ...それはオブジェクトが 1 つだけの場合でも... get name of every person whose name starts with "P" --> {"Poppleton"} -- ..."every" についてオブジェクトがない場合でも... get name of every person whose name starts with "Q" --> {} -- ...ただし、範囲ではその両端が存在する必要がある。 get name of people 1 through 17 --> Error: Can't get person 17.
このルールに違反するコマンド(たとえば、範囲を指定されて、値を返す場合とリストを返す場合があるなど)は、何が起きたかを知るためにロジックを作成する必要が生じるため、使用するのが面倒です。詳細については、「キー形式」 を参照してください。
最も内側にある tell ブロックの対象がターゲットです。ターゲットを利用して、スクリプトで省略されるパラメータを補います。場合によっては、AppleScript がこれを代わりにやってくれます。ターゲットは通常、ダイレクトパラメータに対応するので、コマンドがパラメータを要求しているのに、スクリプトで提供していない場合は、AppleScript が自動的にターゲットをダイレクトパラメータとして渡します。しかし、場合によっては、ターゲットが前置詞パラメータとして意味をなす場合もあります。add x to y を考えてみましょう。この代わりに、tell y to add x と記述しても理にかなっています。アプリケーションは、欠落している to パラメータを検出して、対象パラメータからターゲットを選び出すことができます。対象パラメータは、AppleScript がターゲットを渡す付加的なパラメータです。
AppleScript コマンドの戻り値は、ステータスコードやメッセージではなく、必ずコマンドの結果の値またはオブジェクトでなければなりません。結果がない(つまり、コマンドがアクションを実行するだけ)場合は、何も返さないようにします。
エラーを示すには、イベントハンドラからゼロ以外のエラーコードを返すか、応答に kOSAErrorNumber パラメータを設定します。該当する場合、特に -1700 〜 -1799 の AppleEvent エラー範囲では、標準エラーコードを使用します(Apple Event Manager Reference の 「Result Codes」 を参照)。kOSAErrorOffendingObject など、追加のエラーパラメータ(完全なリストについては OSA.h を参照)の使用を強くお勧めします。できるだけ明確なエラーを返すのがこの狙いです。たとえば、コマンドが番号を要求しているのに、スクリプトからリストを渡したとします。
| 悪い例 | Return paramErr→ error: Parameter error. |
| より良い例 | Return errAECoercionFail→ error: Can't make some data into the expected type. |
| 最良の例 | Return errAECoercionFail,set kOSAErrorOffendingObject to the given value,set kOSAErrorExpectedType to cNumber→ error: Couldn't make {1, 2, 3} into a number. |
ユーザによる操作の取り消しはエラーとします。このような場合は、userCanceledErr (-128) を使用します。
スクリプティングのポイントの一部は完全に自動化された機能を作成することであるため、スクリプティングコマンドがユーザとの対話を必要とするべきではありません。今までに保存されたことがないファイルを、場所の指定なしで save しようとするなど、コマンドから情報が欠落している場合はユーザとの対話も許容できますが、スクリプトが対話なしで機能できるように、必ずパラメータを用意する必要があります。コマンドは決して、確認を求めるべきではありません。たとえば、Finder の「ゴミ箱を空にする」メニューコマンドは確認を求めますが、empty trash スクリプトコマンドは確認を求めません。
スクリプティングコマンドに応えてユーザとの対話を試みる前に、AEInteractWithUser を呼び出します。エラーが返された場合は、対話をしてはなりません。ユーザインタフェースなしで済ませるか、失敗にします。これは、スクリプトで対話を許容するかどうか指定することを可能にします。
自分がたくさんのオプションを持つコマンドを実装していることに気づくときがあります。そのとき、個別の Boolean パラメータを作成する誘惑に駆られるかもしれません。パラメータの数が少なければ、「with a, b, and c.」 のように記述できて良いように思えます。しかし、この手法を使いすぎると、それらのイベントに関して、パラメータの長いリストを持つ扱いにくい用語説明エントリができてしまうことがあります。
これには、2 つの解決策があります。オプションまたはオプションセットに対して列挙子のリストを受け取れるパラメータを作成するか、コマンドを、より特化した機能を持つ複数のコマンドに分割することで、それぞれのオプション数を少なくします。
たとえば、次のように、たくさんのパラメータを使用してどんなタイプの解析でも実行する 1 つのコマンドを作成する統計パッケージを考えてみましょう。
analyze data set -- 25 個の Boolean オプション
これは次のように、分析機能を複数のコマンドに分割して、それぞれに Boolean パラメータの小さなグループを持たせたほうがよいでしょう。
cluster data set
correlate data set
fit curve data set
同時に指定しないパラメータが存在することに気付いたら、それはコマンドを分割する必要がある可能性を示します。
予期していない余分なパラメータを持ったコマンドを受け取った場合、それらのパラメータを単に無視して、エラーを返さないようにします。同様に、keyMissedKeywordAttr イベント属性をチェックする必要はありません。その有用性はなくなっており、Mac OS X 10.2 以降では必ず false が返されます。
標準スイートでは 15 のコマンドを定義しています。アプリケーションでは、独自のコマンドを作成するより、これらを優先して使用するべきです。すべてのコマンドがすべてのアプリケーションにとって有用であるわけではありません。関係のないもの(たとえば、「システム環境設定」のように、書類を扱わないアプリケーションにおける open)は、用語説明に含めるべきではありません。
ほとんどの場合、「specifier」 型のパラメータでは、任意の数のオブジェクトを指定できます。コマンドが単数、範囲、および every 指定子で正しく機能し、前述の「範囲はリストを返す」ルールに従っていることを確認してください。
位置パラメータに関して一言
いくつかのコマンドは、位置指定子型のパラメータを取ります。これは挿入ポイント指定子やコンテナオブジェクト指定子であったり、たいていの場合は範囲指定子であったりします。
挿入ポイント は、beginning(先頭)、end(末尾)、または別の指定子の before(前)や after(後)にオブジェクトを挿入できる位置です。他の指定子としては範囲または every があります。後者の場合、結果の挿入ポイントすべてについて処理が繰り返されます。
add photo "On the beach" to end of album "Vacation" move paragraph 1 to after paragraph 3 make new word at beginning of every paragraph with data "Note:"
コンテナオブジェクト指定子は、オブジェクトの追加、移動、作成などを行うコンテナです。アプリケーションがコンテナ内で適切な位置を選択します。この場合も、範囲または every 指定子を指定できます。
add photo "On the beach" to album "Vacation" duplicate message 1 to every mailbox whose name contains "backup"
一部のコンテナはコンテナ指定子しか受け入れないことがあります。詳細については、「オブジェクト指定子」を参照してください。
add 指定子 [to 位置指定子]
-- 新しい位置にあるオブジェクトを指す指定子を返す
指定したオブジェクトをコンテナ(内の位置)に追加し、新しい位置を返します。to パラメータを省略すると、ターゲットから推論されます (たとえば、tell album "Waterfowl" to add photo 4 の場合、to 位置はターゲット album "Waterfowl" になります)。
アプリケーションが一対一および一対多の関係のみを持っている場合は、このコマンドをサポートしないでください。詳細については、「多対多の関係」を参照してください。to パラメータに範囲または every 指定子を使用すると、任意の数のコンテナにオブジェクトを追加できるとみなされます。すべてのアプリケーションに当てはまるとは限りません。
close 指定子 [saving yes | no | ask]
指定したオブジェクトを閉じます。書類やウインドウがある場合は、閉じれるようにします。アプリケーションでは、他のオブジェクトにも close を適用し、パラメータを追加することができます。
count 指定子
-- 指定されたオブジェクトの数を返します。
指定されたオブジェクトの数を返します。このコマンドは、「範囲はリストを返す」ルールの例外です。count に対して範囲または every を指定すると、指定したオブジェクトの数が返されますが、every の場合はゼロになる可能性があります。存在しないオブジェクトを count しようとするとエラーになります。count に名前などの単数指定子を使用するのは有効ですが、1 が返されるか、オブジェクトが存在しなければ失敗するため、あまり有用ではありません (このような場合は、スクリプトで exists を使用します)。歴史的な経緯から、count は each パラメータを定義していましたが、必要なかったので廃止されました。
delete 指定子
指定したオブジェクトを、入っているコンテナから取り除いて破棄します。delete は問答無用で必ずオブジェクトを削除しなければなりません。(Finder のように)ゴミ箱のような機能を持ちたい場合は、trash オブジェクトを定義し、ユーザがオブジェクトをそこに move(移動)できるようにします。アプリケーションモデルによっては、オブジェクトを削除するとそのコンテナも削除される場合があります。つまり、コンテナが要素を持たないことが不可能な場合です。
duplicate 指定子
[to 位置指定子]
[with properties レコード]
-- 新規オブジェクトの指定子を返します。
指定したオブジェクトを指定の位置に複製し、オプションとして with properties パラメータが指定された場合にはプロパティの一部を変更し、新しいオブジェクトの指定子を返します。to 位置の指定がなければ、新しいオブジェクトを同じコンテナ内に作成し、適切に変更します (たとえば、duplicate thing "Bob" は、"Bob copy" という名前の新しいオブジェクトが作成されることが考えられます)。新しいオブジェクトが競合を引き起こした場合にどうなるかは規定されていません。アプリケーションは、単純に失敗とすることもできますし、新しいオブジェクトを調整して競合を解決したり、競合を処理する方法を指定する追加パラメータを定義することができます。
exists 指定子
-- オブジェクトが存在すれば true を返し、存在しなければ false を返す。
指定したオブジェクトがすべて存在すれば true を返し、存在しなければ false を返します。ほとんどのコマンドと異なり、存在しないオブジェクトを指定してもエラーにはなりません。単に、結果が false になるだけです。count と同様に、exists も「範囲はリストを返す」ルールの例外です。範囲指定子は範囲内にあるすべてのオブジェクトが存在する場合にのみ true を返し、every 指定子は、そのようなオブジェクトが少なくとも 1 つ存在する場合に true を返します。
get 指定子 [as クラス]
-- 指定されたオブジェクトの値を返す。
指定されたオブジェクトの値を返します。get は AppleScript に組み込まれているため、用語説明で定義する必要はありません。異なるパラメータを使用して、get を再定義してはなりません。
make [new] クラス
[at 位置指定子]
[with properties レコード]
[with data 任意のもの]
-- 新規オブジェクトを指す指定子を返す。
新しいオブジェクトを作成し、その指定子を返します。at はオプションです。このオプションが省略された場合は、適切なデフォルト位置を選択します。現行書類の先頭または末尾が一般的な選択肢です。理想的には、with パラメータは両方ともオプションであるべきですが、一部のクラスではどちらか一方(両方ではない)が必須の場合があります。with properties と with data を区別するように注意してください。アプリケーションが作成したオブジェクトのデフォルトプロパティをオーバーライドする場合は、with properties を使用します。外部ソースのデータ(文字列やファイルなど)でオブジェクトが効率的に定義される場合は、たとえ作成されるオブジェクトのプロパティのいずれかがそのデータ(のポインタ)であっても、with data を使用します。
move 指定子 to 位置指定子
-- 新しい位置にあるオブジェクトを指す指定子を返す。
指定されたオブジェクトを新しい位置に移動し、新しい位置にあるオブジェクトの指定子を返します。to パラメータは必ず必要であり、範囲または every 指定子は使えません。
open ファイル | ファイルのリスト
-- 作成したアプリケーションオブジェクトへの指定子を返す。
指定されたファイルを開き、その新しいアプリケーションオブジェクト(たいてい documents)を返します。標準バージョンは書類ファイルを開くように設計されていますが、アプリケーションでは open を他のオブジェクトに適用し、パラメータを追加することができます。
print 指定子
[with properties プリント設定]
[print dialog ブール値]
指定されたオブジェクトをプリントします。ほとんどのアプリケーションでは、オブジェクトはいつも書類ですが、これは必須ではありません。with properties および print dialog パラメータのサポートは Mac OS X 10.3(Panther)で追加されました。詳細については、TN2082 を参照してください。
quit [saving yes | no | ask]
アプリケーションを終了します。saving パラメータの値(デフォルト値は ask)は、結果の close コマンドに渡されます。すべてを自動的に保存するアプリケーションでは、saving パラメータを定義するべきではありません。
remove 指定子 [from 指定子]
指定されたオブジェクトをそのコンテナから取り除きます。from パラメータが省略されている場合には、可能であれば、ダイレクトパラメータから推論します (たとえば、remove first photo of album 1 の場合、from パラメータは album 1 と理解されます。しかし、remove photo id 437 の場合、どこから取り除くべきか判断できないので、アプリケーションはエラーを返さなければなりません)。アプリケーションが一対一および一対多の関係のみ持っている場合は、このコマンドをサポートしないでください。アプリケーションモデルによっては、remove でオブジェクトを削除する場合としない場合があります。詳細については、「多対多の関係」を参照してください。アプリケーションモデルによっては、オブジェクトを取り除くとそのコンテナが削除される場合があります。つまり、コンテナが要素を持たないことが不可能な場合です。
save 指定子 [in ファイル]
指定されたオブジェクトを、ファイルが指定されていればそのファイルに保存します。in が指定されていない save は、「保存」メニューコマンドのように機能し、ファイルの場所をユーザに尋ねることができます。保存されたことのないファイルを指定した save in は「別名で保存」のように動作します。保存したことのあるファイルを指定した save in は「保存」のように振る舞います。
select 指定子
ユーザインタフェース内の指定されたオブジェクトを選択します。詳細については、「セレクションのスクリプティング」を参照してください。
set 指定子 to 値
-- 割り当てられた値を返す。
指定されたオブジェクトを特定の値に設定し、割り当てた値、つまり完全に評価された to パラメータを返します。これは必ずしも、パラメータの元の値と同じではありません(特にオブジェクト指定子の場合)。ほとんどのアプリケーションでは、ダイレクトパラメータは実際のオブジェクトを値に設定できないため、プロパティ指定子でなければなりません。set は AppleScript に組み込まれているため、用語説明で定義する必要はありません。異なるパラメータを使用して、set を再定義してはなりません。
ビューではなく、モデルのスクリプティングに関してこれだけ話してきたので、このセクションにはおそらくちょっとした驚きを感じるでしょう。とはいえ、ビュー指向のスクリプタビリティについて少し取り上げるのも有益です。ユーザがスクリプティングで行うことの 1 つは、新しいコマンドをアプリケーションに追加することであり、それを効果的に行うためには、何が可視状態になっていて、何が選択されているかを知る方法が必要です。
「オブジェクト」で述べたように、ウインドウは前面から背面へインデックスを順に付けるべきであるため、window 1 または first window は必ず最前面のウインドウになり、window -1 または last window は必ず最背面のウインドウになります。AppleScript 言語では、front と back はそれぞれ、first と last の同義語であるため、これは暗黙の了解です。
複数の種類のウインドウ(たとえば、書類ウインドウとパレットウインドウなど)を利用する場合は、それらを処理するために別々の window サブクラスを作成します。ウインドウ指定子を渡されたスクリプトは、class プロパティを調べることでウインドウの種類を判別することができます。
モデルオブジェクトを表示するウインドウは、それらが表示するオブジェクトを取得するために、適切に命名されたプロパティを持つ必要があります。その最も一般的な事例が書類ウインドウであり、当該ウインドウの書類を指す document プロパティを持っている必要があります。ウインドウのモデルオブジェクトが 1 つだけであれば、このプロパティがウインドウの暗黙的なサブコンテナになります (sdef の言葉で言えば、contents 要素を使用してこれを定義する、ということになります)。こうしておけば、スクリプトでモデルオブジェクトのプロパティを明示的に調べずに、ウインドウのモデル要素を要求できます。たとえば、documents に words があれば、get word 1 of window 1 は機能します。暗黙的なサブコンテナがなければ、スクリプトで word 1 of document of window 1 と記述する必要があります。逆の関係はお勧めしません。たとえば、書類が暗黙的なサブコンテナとしてのウインドウを持つことはありません。
activate コマンドウインドウをアクティブにする(つまり、前面に表示する)には、activate コマンドを使用し、ウインドウを指定します。ダイレクトオブジェクトの指定なく activate が呼び出されたら、アプリケーション全体を前面に表示するようにします。activate は、書類のように、ウインドウと一対一の関係でマッピングされているオブジェクトにも対応して動作しなければなりません。アプリケーション全体をアクティブにする処理は、システムが自動的に行いますが、それ以外の場合はアプリケーション自体で処理する必要があります。
セレクション は、スクリプティングの世界では、選択されているモデルオブジェクトのみを指します。ダイアログボックスでの選択と混同しないようにしてください。すべてのアプリケーションで、セレクションのスクリプティングをサポートする必要はありません。コントロールパネルのように、非常にシンプルなアプリケーションでは意味がないかもしれません。
セレクションを処理するには、select コマンドと selection プロパティの 2 つの方法があります。選択されているものを知るには、selection プロパティの値を取得します。何かを選択するには、それを select するか、適切な selection プロパティを設定します。
select コマンドselect は、オブジェクト指定子を渡されると、ユーザインタフェースで当該オブジェクトを選択し、アクティブにします。これは以下のことを意味します。
何かを select すると、該当する selection プロパティがそれに合わせて変更されます。
selection プロパティselection プロパティは、そのオブジェクトで現在選択されているものです。アプリケーションには、複数の selection プロパティが存在する可能性があります。
application クラスには、必ず selection プロパティがあります。これを設定すると、select コマンドのように振る舞います。
TextEdit のように書類ごとに 1 つのウインドウがあり、各書類がそれぞれのセレクションを維持している場合は、document クラスに selection プロパティがあります。これを設定すると、当該書類のセレクションが変更されますが、フォーカスは変更されないため、スクリプトからアクティブでないウインドウをアクティブにせずに、そのセレクションを変更することができます。
たとえば、Mail のように複数のウインドウに同じモデルオブジェクトを表示できる場合は、ウインドウには selection プロパティがあります。これを設定すると、前述の場合のように、そのウインドウのセレクションが変更されます。セレクションが純粋にビュー概念である場合、document クラスは(あれば)selection プロパティを持っているべきではありません。
独自のセレクションを持つ他のオブジェクトも、selection プロパティを持つべきです。
selection プロパティは、できるかぎり一貫して同じタイプの値、つまり、必ず単一オブジェクト、必ずオブジェクトのリストなど、必ず何か適切なものでなければなりません。複数の種類の選択可能なデータを扱うアプリケーションでは、アプリケーションの selection プロパティは多くの場合、タイプが変わりますが、これは容認できます。たとえば、Mail では、セレクションがメッセージのリスト、アドレスのリスト、またはテキストであることが可能です。
テキストベースのオブジェクトモデルでは、セレクションの値は選択したテキストの位置を示す指定子であり、実際のテキストではありません。たとえば、characters 1 through 3 of document 1 であり、"The" ではありません。これにより、スクリプトは選択対象と選択されているテキスト(下記を参照)のどちらも変更でき、セレクションを基準とする相対位置を指示することができます。選択されているテキストを取得するには、contents of the selection を get します。
セレクションが一定範囲の文字である場合は、characters 1 through 3 のように何らかの範囲を返します (ただし、次のパラグラフを参照)。セレクションが挿入ポイントだけで、文字を含んでいない場合は、下記のテーブルに示すように、insertion point クラスを使用します。
一部のアプリケーションは、テキストオブジェクトモデルを十分に認識しており、文字より大きな単位でセレクションを報告します。たとえば、ユーザが 3 番目のパラグラフを選択した場合、selection プロパティは characters 173 through 254 ではなく、paragraph 3 と報告します。そのパラグラフの 2 番目の語を選択すると、word 2 of paragraph 3 と報告されます。このような振る舞いを奨励しますが、必須ではありません。
分離しているテキストセレクションをサポートする場合、セレクションが分離していなければ selection プロパティを単一指定子とし、分離していれば指定子のリストとします。これは「必ず同じ型の値にする」ガイドラインに違反しますが、たいていの場合、その動作に対する驚きはこちらのほうが少ないでしょう。
| Now is the time | insertion point before character 1 |
| Now is the time | insertion point after character 3insertion point after word 1 |
| Now is the time | characters 1 through 3word 1 |
| Now is the time | {characters 1 through 3, characters 12 through 15}{word 1, word 4} |
(実際には、それぞれの指定子には 「of document 1」 のような指定子が続きますが、 簡単にするために、ここでは省略しています。)
セレクションプロパティ自体に書き込んでも選択対象が変わるだけです。実際のテキストを変更するには、セレクションのプロパティまたは要素に書き込む必要があります。前述のように、selection はサブ要素(この場合は、characters、words など)へのアクセスを可能にする必要があります。セレクション全体を取得するには、contents プロパティを使用します。プロパティまたは要素を設定すると、そのテキストが変更され、セレクションの長さが変わる可能性があります。たとえば、次のようになります。
select word 3 |
one two four |
set contents of the selection to "thref" |
one two thref |
set last character of the selection to "e" |
one two three |
テキストモデルでは、セレクションを基準にして before と after を使用することで、セレクションをそれ自体に対して相対的に移動することができます。ポイントを選択するには、insertion point クラスを使用します。beginning と end も使用できます。
select word 1 |
Now is the time |
select word after the selection |
Now is the time |
select insertion point after the selection |
Now is the time |
select beginning |
Now is the time |
select end |
Now is the time |
前述のように、set the selection to を使用しても、同じ効果が得られます。
アプリケーションによっては、1 つのウインドウ内に複数のビューが存在し、それぞれにセレクションを設定できます。たとえば、Mail のビューアウインドウは、選択されているメールボックス、そのメールボックス内で選択されているメッセージ、およびメッセージ内で選択されているテキストと、最大 3 つのセレクションを持つことができます。任意の時点でフォーカスを得るのはそのうちの 1 つだけであり、それによってアプリケーションとウインドウ全体の selection プロパティの値が決まります (どこにフォーカスがあるか判断するのが難しい場合は、「カットまたはコピーを選択すると、どのデータがクリップボードに行くか ?」を考えてください。
このような場合に、各種サブセレクションを取得するには、「selected 対象」 要素を追加します。たとえば、Mail では、要素タイプの selected mailbox、selected message、および selected text を定義します。
用語説明の複数の場所で同じ用語を使用する場合、それらはすべて、同じ 4 バイトコードを使用する必要があります。たとえば、input をパラメータ、プロパティ、および列挙子として使用する場合は、3 か所すべてに同じタイプコードを使用します。反対に、複数の場所に同じタイプコードを使用する場合には、それらはすべて、同じ用語を使用する必要があります。これはシステムまたはフレームワークが提供する用語説明から継承した用語とコードにも適用されます。たとえば、クラスの color プロパティを定義する場合、これは AppleScript の用語説明と Cocoa の NSCoreSuite スクリプトスイートで定義されているので、そのコードと同じ 'colr' でなければなりません。このルールに従わないと、スクリプトをコンパイルまたはデコンパイルするときに、失敗したり、奇妙な変更が加わる(AppleScript が、オリジナルの用語を最後の定義に変更する)ことになります。
aete の用語説明は、同義の用語やコードを定義するために、このルールの違反を実際に利用しています。sdef では、そのsynonym要素を通じて同義語を直接サポートしています。詳細については、sdef の文書を参照してください。
第一に、AppleScript の基本構文は英語指向です。別の言語の識別子を利用すると奇妙になります。さらに、それはおそらく機能しません。AppleScript の識別子には非 ASCII 文字を含めることができません。そのため、ほとんどの言語で、記述できることが大きく制限されます。
Cocoa はアップルのアプリケーションフレームワークです。これは積極的なオブジェクト指向で、スクリプタビリティを簡単に追加することができます。文書については、「Scriptable Applications」を参照してください。ただし、Cocoa のデフォルトのスクリプティングサポート機能は、必ずしもすべての場合においてスクリプティングインタフェースガイドラインに準拠しているわけではありません。幸いにも、以下のような回避方法があります。
aete をアプリケーションに追加するCocoa アプリケーションは現在、スクリプトスイートのセットを提供することでスクリプタビリティを定義しています。それぞれのスクリプトスイートは、スイート定義(.scriptSuite)とスイート用語(.scriptTerminology)の 2 つの plist ファイルで構成されます。Cocoa に、これらに基づいて aete フォーマットの用語説明を生成させることが可能ですが、スクリプトスイートで表現できない概念があるため、その結果は標準に届かない傾向があります (また、用語説明を利用するのにアプリケーションも起動する必要があるため、スクリプト作成者は面倒に思います)。
したがって、アプリケーションの一部として同じような aete 用語説明を作成するべきです。これを行う最も簡単な方法は、sdef を使用して用語説明を作成し、それから sdp(1) を使用して 3 つのファイル(.scriptSuite、scriptTerminology、および aete.r)をすべて生成することです。
make の at パラメータを要求しない初期設計の誤りのために、Cocoa はデフォルトで make の at パラメータを要求します。LocationRequiredToCreate 属性を使用して、これを必ずオーバーライドしてください。詳細については、「Cocoa Scripting release notes」を参照してください。sdef を使用して用語説明を作成する場合は、sdp(1) によって正しい属性が追加されます。
Cocoa スクリプティングスイート定義には、完全に厳密になれないという問題があります。フレームワークから継承する定義(特に、Standard と Text スイート)はほぼ完全に汎用的なものです。アプリケーションでサポートしていないコマンドも依然として参照が可能で、ダイレクトパラメータは単に 「reference」 型として定義されており、application は必要かどうかに関係なく、document 要素を抱えています。この問題は、アプリケーション用の aete 用語説明を作成すれば回避できますが(前述を参照)、その分だけ作業が増えます。sdef を使用して aete を生成する場合は、現在のところ同じ問題を抱えているため、sdef バージョンの Standard スイート(/Developer/Examples/Scripting Definitions/NSCoreSuite.sdef)も変更する必要があります。
Cocoa スクリプティングのデフォルトのエラーメッセージは、分かりやすい英語(「Can’t get window 17」 など)ではなく、汎用的なプログラマ言葉(「NSReceiverEvaluationScriptError: 4」 など)で書かれています。Mac OS X 10.3(Panther)では、[NSScriptCommand currentCommand] を呼び出し、次に返されたオブジェクトの -setScriptErrorNumber: と -setScriptErrorString: を呼び出すことで、独自のエラー番号とメッセージを設定することができます。詳細については、「NSScriptCommand documentation」を参照してください。