メッセージの 操作
以下の情報に目を通して、スクリプト内のメッセージの送信、処理または管理に利用する特定のすべてのメカニズムに関する内容を理解するようにしてください。
ハンドラ
SenseTalkスクリプトは、ハンドラで構成されます。ハンドラは、送られてくる特定のメッセージをスクリプトがどう処理するかを定義するスクリプトの一部です。ハンドラには、次の3つの主要なタイプが存在します。コマンドハンドラ(onハンドラとも呼ばれる)、 関数ハンドラ、および汎用ハンドラ(toハンドラとしても知られる)。さらに、getPropおよびsetPropの2つの特別なハンドラも存在します。詳細は、プロパティを参照してください。
スクリプトに同じメッセージ名向けの汎用ハンドラと特定のハンドラ(onまたは関数ハンドラ)の両方が含まれる場合は、特定のハンドラが常に優先され、そのメッセージを受け取ります。toハンドラは、その他のタイプのメッセージを受け取ります。スクリプトに特定のメッセージ向けの3種類すべてのハンドラが含まれる場合は、onハンドラはその名前のコマンドメッセージを受け取り、関数ハンドラは関数メッセージを受け取ります。そしてtoハンドラが呼び出されることはありません。
to、to handle
挙動:toまたはto handleキーワードは、コマンドメッセージと関数メッセージの両方を受け取ることができる汎用ハンドラを宣言します。ハンドラの呼び出し方に応じてハンドラが異なるアクションを実行する必要がある場合は、messageType()関数を使用すると、ハンドラがコマンドとして呼び出されたか、または関数として呼び出されたかを確認できます。
スクリプトがメッセージ名と一致するコマンドメッセージまたは関数メッセージのどちらかを受け取ると、本ハンドラのステートメントが実行されます。ハンドラに渡される受信パラメータ値には、メッセージ名の後で宣言される、対応するパラメータ名(パラメータ名1、 パラメータ名2、パラメータ名N)が割り当てられます。
構文:
to {handle} メッセージ名 {{with} パラメータ名1 {, パラメータ名2...} }
ステートメント
end メッセージ名
例:
to handle increaseSize amount
if amount is empty then add 1 to my size else add amount to my size
end increaseSize
on
挙動:onキーワードは、コマンドハンドラを宣言するのに使用し、endキーワードはこれを終了するのに使用します。
オブジェクトがハンドラ名と一致するコマンドメッセージを受け取ると、そのハンドラのステートメントが実行されます。ハンドラに渡される受信パラメータ値には、ハンドラ名の後で宣言される、対応するパラメータ名(パラメータ名1、パラメータ名2、パラメータ名N)が割り当てられます。
以下の例では、addToTotalコマンドメッセージが追加されます。パラメータをメッセージと一緒に渡す場合は、その値はnewAmount変数内で入手でき、そうでない場合は変数はemptyになります。
on ハンドラ名 {パラメータ名1 {, パラメータ名2...} }
ステートメント
end ハンドラ名
例:
on addToTotal newAmount
add newAmount to global total --global変数に totalを格納します
end addToTotal
function
挙動:functionキーワードは、関数ハンドラを宣言します。スクリプトが関数名と一致する関数メッセージを受け取ると、本ハンドラのステートメントが実行されます。ハンドラに渡される受信パラメータ値には、関数名の後で宣言される、対応するパラメータ名(パラメータ名1、パラメータ名2、パラメータ名N)が割り当てられます。戻り値は、関数呼び出しの値として、呼び出し元のスクリプトに戻されます。
構文:
function 関数名 {パラメータ名1 {, パラメータ名2...} }
ステートメント
return 戻り値
end 関数名
例:
function getTotal
return global total
end getTotal
Initialハンドラ
to、onまたはfunctionを利用して明示的に宣言されるハンドラに加えて、スクリプトの先頭行がオブジェクトのinitialハンドラとして参照されます。多くのスクリプトはinitialハンドラのみで構成され、to、onまたはfunctionを利用して明示的に名前が付けられたハンドラは使用されません。initialハンドラは常に、コマンドメッセージと関数メッセージの両方に応答できる汎用の「to handle」ハンドラとして扱われます。
スクリプト内の最初の名前付きハンドラまでのすべてのステートメント(存在する場合)は、名前のないinitialハンドラの一部であるかのように扱われます。スクリプトをファイルから直接ロードする場合は、initialハンドラにはそのファイルの名前と同じ名前が(拡張子と禁則文字を除いて)割り当てられます。スクリプトファイル以外のオブジェクトについては、initialハンドラには名前<initialHandler>が割り当てられます。
注:スクリプトに実際にスクリプトと同じ名前のハンドラが含まれる場合は(「to handle scriptFileName」など)そのハンドラが優先され、最初の名前付きハンドラの前のスクリプトの開始行は無視されます。
注:ディスク上に存在するスクリプトオブジェクトにメッセージを送信する場合は、SenseTalkはそのスクリプトファイルを読み取り、そのスクリプトをメモリにキャッシュします。その後、オブジェクトが別のメッセージを受け取る場合は、SenseTalkはオブジェクトがそのメッセージ向けのハンドラを持っているかどうかを素早くチェックできます。一部の(非常に稀な)状況では、実行中にSenseTalkにスクリプトの更新状態をチェックさせることが望ましい場合があります。このような状況では、the watchForScriptChangesグローバルプロパティをtrueに設定できます(デフォルト設定ではfalse)。これにより、SenseTalkはオブジェクトがメッセージを受け取るたびに、ファイルが更新されたかどうかをチェックすることが可能になります。ファイルが更新されたら、そのファイルが再度読み込まれ、新しいハンドラが使用されます。実行中は、ハンドラの実行バージョンは変わりません。
getProp、setProp
オブジェクトのスクリプトには、標準のコマンドと関数ハンドラの他に、そのオブジェクトのプロパティを操作するための2つの特別なタイプのハンドラ(プロパティ値を指定するためのgetPropハンドラと、新しいプロパティ値を受け取るためのsetPropハンドラ)が含まれる場合があります。
オブジェクトのプロパティを読み取る場合は常に、そのプロパティ向けのgetPropメッセージがオブジェクトに送られます。オブジェクトがメッセージを処理する場合は、オブジェクトによって戻される値がそのプロパティの値として使用されます。プロパティ値を変更すると、setPropメッセージが、パラメータとしての新たな値と一緒にオブジェクトに送られます。オブジェクトがそのメッセージ向けのsetPropハンドラを持っている場合は、そのハンドラが呼び出され、そうでない場合はプロパティが直接設定されます。
例えば以下は、長さと幅に基づき、オブジェクトのareaプロパティを指定するハンドラです。
getProp area
return my length * my width
end area
オブジェクトがプロパティの設定を管理する必要がある場合もあります。以下に、オブジェクトのareaの設定により、実際に長さを変更する例を示します。
setProp area newArea
set the length of me to newArea
my width
end area
オブジェクトがそのプロパティ向けのgetPropまたはsetPropハンドラ内部からいずれかの固有のプロパティにアクセスする場合は、SenseTalkはgetPropまたはsetPropハンドラを再帰的に呼び出すのではなく、本プロパティに直接アクセスします。
my directプロパティ
挙動:任意の関数またはgetPropもしくはsetPropメッセージを送らずに、オブジェクトが固有のプロパティにアクセスできるようにします。これは、特別な構文my direct プロパティ名(またはmy direct property プロパティ名)を利用して実行できます。
構文:
my direct プロパティ名
my direct property プロパティ名
例:
getProp age -- 自分の年齢
return (the date - my direct birthDate) div 365.25 days
end age
メッセージを渡す
ハンドラは、受け取ったメッセージを処理しないことを選択するか、または何らかのアクションの実行後にpassコマンドを利用してメッセージパッシングパス内の後続の別のスクリプトにメッセージを渡すことができます。
passコマンド
挙動:現在のメッセージを、メッセージパッシングパス内の次のオブジェクトに渡します。これにより、現在のハンドラの実行は終了します。汎用的なmessageという用語ではなく、ハンドラ名または関数名を指定する場合は、その名前は現在のハンドラの名前と同じである必要があります。on、function、getPropまたはsetPropを使用する場合は、現在のハンドラタイプと一致している必要があります。
構文:
pass ハンドラ名または関数名
pass {message | on | function | getProp | setProp}
例:
pass message
pass ... and continueコマンド
挙動:passコマンドと同じように、メッセージパッシングパス内の次のオブジェクトに現在のメッセージを渡しますが、メッセージが別の場所で処理された後で現在のハンドラを継続して実行できるようにします。現在のハンドラは、メッセージパッシングパス内の後続の別のオブジェクトでメッセージが処理された後に実行を再開します。別のオブジェクトによって返される値は、pass ... and continueコマンドのすぐ後でthe resultにて入手できます。pass ... and continueコマンドの実行後に、(いずれかのpassコマンドを使って)そのメッセージを後から渡そうと試みても、メッセージが同じオブジェクトに2度送られることはないため、実際にメッセージを渡すことはできません。
構文:
pass ハンドラ名または関数名 and continue
pass message and continue
例:
pass message and continue
pass ... without helpingコマンド
挙動:メッセージパッシングパス内でヘルプ対象のオブジェクトに続く次のオブジェクトにメッセージを渡します。本コマンドをヘルパー内で使用する場合に、passコマンドとの違いが現れます。つまり、ヘルパーは「このメッセージではヘルプができない」ということを示します。ヘルパーのヘルパーにはメッセージを処理するチャンスは与えられませんが、メッセージは、ヘルプ対象オブジェクトの後続のヘルパーや、メッセージパッシングパス内の後続の別のオブジェクトに渡されます。本コマンドが実行されると、現在のハンドラは実行を停止します。
構文:
pass ハンドラ名または関数名 without helping
pass message without helping
例:
pass message without helping
pass original message to ...コマンド
挙動:pass original message to ...を利用すると、現在のメッセージを直接別のオブジェクトに渡すことができます。これは、現在のメッセージをメッセージパッシングパス内の次のオブジェクトに渡すその他の形式のpassコマンドとは異なります。
この形式のpassコマンドは、オリジナル(未達)のメッセージを処理するために別のオブジェクトに渡そうとするundeliveredMessageハンドラ内での使用を目的としています。その別のオブジェクトがメッセージを処理すればそれで終わりとなり、現在のハンドラの実行が終了します。別のオブジェクトがメッセージを処理しなければ、現在のハンドラにおいて実行が継続します。このようにして、undeliveredMessageハンドラは、処理を行えそうな1つ以上の別のオブジェクトにオリジナルメッセージを渡すことを試みることができます。詳細は、未達メッセージを参照してください。and continueを指定する場合は、メッセージが別のオブジェクトによって処理されたかどうかに関わらず、メッセージが渡された後で現在のハンドラの実行が再開されます。
構文:
例:
pass original message to alterEgo
callStack()関数
挙動:callStack()関数はSenseTalk Frameオブジェクトのリストを返し、現在の実行フレームに関する情報を提供します。現在のハンドラの呼び出し方に関する情報を入手したい場合は、callStack()を呼び出します。
構文:
the callStack
callStack()
例:
put property "Line" of the last item of the callStack into currentLine