メッセージ
SenseTalkは、あるオブジェクトから別のオブジェクトに_メッセージ_を送信することで動作するオブジェクト指向言語です。メッセージがオブジェクトに送信されると、そのスクリプトにそのメッセージの_ハンドラ_がある場合、応答することができます。特定のメッセージのハンドラを持っていないオブジェクトは、そのメッセージを他のオブジェクトに引き渡します。ハンドラの使用方法の詳細は、ハンドラをご覧ください。
オブジェクトが_何かを行う_のは、_メッセージ_を受け取った時だけです。オブジェクトは自己にメッセージを送信することも、他のオブジェクトやスクリプトが存在する環境から送信されることもあります。例えば、スクリプトがコマンドラインから呼び出されると、スクリプトの名前に基づいたメッセージが送信され、スクリプトが実行されます。
最初に知っておくべきことは、メッセージがオブジェクトに送信された時、それを受け取って処理することも無視することもできる、ということです。メッセージとその送信方法については、引き続きお読みください。
メッセージの送信
スクリプトが実行されているとき、コマンドを実行するたびにメッセージが送信されます。メッセージは常に単語であり、最も単純なメッセージ送信文は単語一つのコマンドで、送信されるメッセージの名前です。例えば、このスクリプトの2行目は、"greetTheUser"というメッセージを送信します。
put "Hello, World!"
greetTheUser
put farewellMessage()
このスクリプトでは、1行目と3行目のput
コマンドもメッセージを送信します。実際、SenseTalkの基本的な制御構造を除いて、スクリプトのほぼすべてのコマンドがメッセージを送信します。上記の“farewellMessage()”関数への呼び出しのような関数呼び出しも、メッセ出しもメッセージを送信します。
コマンドメッセージと関数メッセージ
SenseTalkは実際には2種類のメッセージを送信します。コマンドメッセージはコマンドによって送信され、上述の例のgreetTheUser
のようなものです。関数メッセージは関数呼び出しによって送信され、上述の例のfarewellMessage()
のようなものです。2つのメッセージタイプは、それらを受け取るハンドラのタイプを除いて同一です(ハンドラを参照)。関数の呼び出し方についての詳細は、関数を参照してください。コマンドの使用方法についての詳細は、コマンドとコメントを参照してください。
メッセージはどこに送信されるのか?
私たちは先ほど、 メッセージはオブジェクトがお互いに通信するために使われると述べましたので、上記の"greetTheUser"と"put"メッセージはどこに送信されるのか、どのオブジェクトがこれらのメッセージを受け取るのか、疑問に思うかもしれません。答えは非常にシンプルで、多少驚くかもしれませんが、これらのコマンドを含むオブジェクトはこれらのメッセージを自身に送信します!
初めてみると、オブジェクトが自身にメッセージを送信することはあまり役に立たないように思えるかもしれませんが、実際にはオブジェクトが処理しない任意のメッセージは、他のオブジェクトが可能性として処理したり、最終的にはSenseTalkの組み込みコマンドや関数のいずれかが処理したりします。
必要に応じて、メッセージを他の特定のオブジェクトに直接送信することもできます。これは、tell
コマンド、send
コマンド、run
コマンド、run
関数、角括弧メッセージ構文を使用したり、of
、.
または 's
を以下のように使用することで実現します:
put the salary of writer into authorPay -- "salary" を writer に送信する
get investor's balance("Checking") -- "balance" を investor に送信する
add paycheck.netIncome() to it -- "netIncome" メッセージを paycheck に送信する
メッセージパス
メッセージがオブジェクトに送信されると、そのメッセージはいくつかの異なるオブジェクトを通るパスを辿ります。メッセージが辿るパス上の各オブジェクトは、そのメッセージを処理するチャンスが与えられます。オブジェクトにそのメッセージのハンドラがある場合、そのハンドラの指示が実行されます。それ以外の場合、メッセージは、メッセージを処理するものが見つかるまで、順番にパス上の他のすべてのオブジェクトに提供されます。
通常、メッセージがオブジェクトによって処理されると、それで終わりです。しかし、場合によっては、オブジェクトのハンドラがメッセージをパスに沿って送り続けることを選択することがあり、他のオブジェクトが同じメッセージを処理する機会を得ることがあります(メッセージのパスの pass
コマンドを参照)。
バックスクリプトとフロントスクリプト
全体像を見てみると、メッセージが送信されるオブジェクト(ターゲットオブジェクトと呼ばれる)に加えて、メッセージパスはターゲットオブジェクトとそのヘルパーの前後に他のオブジェクトも含むことがあります。これらのインクルードは、the FrontScripts
と the BackScripts
のオブジェクトと、ホストアプリケケーションが追加する可能性のある他のオブジェクトで構成されています。
The BackScripts
は、ターゲットオブジェクトがメッセージを処理しなかった場合に、メッセージを処理する機会を得るオブジェクトのリストを含むグローバルプロパティです。したがって、オブジェクト(ライブラリやスクリプト)を the BackScripts
に挿入することで、そのオブジェクトのハンドラが任意のスクリプトで利用可能になり、それでも任意の個別のスクリプトが the BackScripts
の振る舞いをオーバーライドするための自分自身のハンドラを提供することを 許します。 The BackScripts
は非常に便利なメカニズムであるため、Start Using
とStop Using
の二つの特別なコマンドが、the BackScripts
にオブジェクトを追加したり削除したりするのを簡単にするために提供されています。
The FrontScripts
は、ターゲットオブジェクトがメッセージを提供される前にメッセージを処理する機会を得るオブジェクトのリストを含む、まれにしか使用されないグローバルプロパティです。これにより、これらのオブジェクトはメッセージをインターセプトし、メッセージをメッセージパスに沿ってパスする前にメッセージをログに記録するなどのタスクに対して、任意のオブジェクトの振る舞いをオーバーライドする可能性を持ちます。
Start Using
コマンド
振る舞い: スクリプトや他のオブジェクトを the BackScripts
に挿入します。これは insert <object> into the BackScripts
コマンドと同等ですが、よりシンプルで読みやすいです。
Syntax:
start using object
insert object into back
insert object into the BackScripts
例:
start using "Folder1/Helper1" // Puts Helper1 (from Folder1) into the BackScripts
関連項目:
Stop Using
コマンド
振る舞い: the BackScripts
に以前挿入されたライブラリやスクリプトを削除します。これは remove <object> from the BackScripts
コマンドと同等ですが、よりシンプルで読みやすいです。
Syntax:
stop using object
remove object from back
例:
stop using "Folder1/Helper1" // Removes Helper1 (of Folder1) from the BackScripts
関連項目:
ヘルパー
メッセージがパスをたどって各オブジェクトに渡されるとき、そのオブジェクトのスクリプトがメッセージのハンドラを含んでいるかどうかチェックされます。もし含んでいれば、そのハンドラが実行されます。そうでなければ、メッセージは順番にそのオブジェクトの各ヘルパーにも渡され、そのうちのどれかがメッセージのハンドラを持っているかどうかを確認します。ヘルパーが適切なハンドラを持ってい るかどうかを確認するとき、そのヘルパーのリストも参照され、またそのヘルパーのヘルパー(もしあれば)も参照されます。全てのヘルパーがチェックされて初めて、メッセージがメッセージパスの次のオブジェクトに渡されます。
the BackScripts
リストのオブジェクトは、メッセージパスの他のオブジェクトが処理しなかったメッセージだけを受け取ります。これらは通常、多くの異なるオブジェクトが必要とする可能性がある基本的な機能を提供するために使用されます。 the FrontScripts
リストのオブジェクトは、ターゲットオブジェクトに到達する前に任意のメッセージをインターセプトして処理する機会を得ます。この機能はまれにしか使用されませんが、特定の状況では強力になる可能性があります。
ホストアプリケーション
メッセージをパスするパスのすべてのオブジェクト(およびそのヘルパー)がそれを処理する機会を得た後、メッセージはホストアプリケーションとSenseTalk自体に配信されます。メッセージが組み込みのコマンドや関数に対応していれば、そのコマンドや関数が処理されます。一部のメッセージはSenseTalkに認識されますが無視されます。メッセージがSenseTalkによって認識されて処理されず、また認識されて無視されない場合、ホストアプリケーションはメッセージと同じ名前のスクリプトファイルを探します。通常、少なくとも呼び出しスクリプトが存在する同じフォルダを見ますし、他のフォルダ も見る可能性があります。スクリプトファイルがメッセージを処理するために見つけられない場合、エラーが発生します。
完全なメッセージパス
メッセージがオブジェクト(ターゲットオブジェクトとして知られる)に送信されると、メッセージの完全なパスには以下のオブジェクトが含まれます、この順序で:
the FrontScripts
に挿入された順序でのオブジェクト(最近挿入されたオブジェクトが最後にメッセージを受け取る)とそのヘルパー- ターゲットオブジェクトとそのヘルパー
the BackScripts
にあるオブジェクト(最近後ろに挿入されたオブジェクトが最後にメッセージを受け取る)とそのヘルパー- ホストアプリケーションとSenseTalk自体
- ホストアプリケーションによって特定されたフォルダの他のスクリプトファイル
メッセージのハンドラが見つかると、そのハンドラが実行されます。そのようなハンドラがメッセージを渡さない場合、それは処理され、これ以上進まないと考えられます。ただし、ハンドラは pass
コマンド(またはそのバリアント)を使用してメッセージを渡すことを選択することもあります。そうすると、メッセージは処理されていないかのようにメッセージのパスを続け、後続のオブジェクトがそのメッセージを受け取るチャンスを得ます。
ターゲット
メッセージはメッセージパス上のいくつかの異なるオブジェクトによって処理される可能性があるため、これらのオブジェクトはメッセージが送信されたオブジェクトを見つける必要があるかもしれません。これが the target
の目的で、ターゲットオブジェクトを特定します。たとえば、the BackScripts
に挿入されたオブジェクトは incrementAccessCount
ハンドラを持つかもしれません。このハンドラは、実行するたびにカウンタを増やします。次のようになります。
on incrementAccessCount
add 1 to the accessCount of the target
end incrementAccessCount
ここでは、自身の accessCount
プロパティに単一のカウンタを維持するのではなく、incrementAccessCount
メッセージを受け取ったオブジェクトの accessCount
プロパティを更新しています。
メッセージの受け渡し
ハンドラは受け取ったメッセージを処理しないことを選択するか、またはいくつかのアクションを実行してから、pass
コマンドを使用してメッセージをメッセージパスの後続のスクリプトに渡すことができます。ハンドラーの作業についての詳細は、Handlersを参照してください。
Pass
コマンド
振る舞い: 現在のメッセージをメッセージパスの次のオブジェクトに渡します。これにより、現在のハンドラの実行が終了します。もし handlerOrFunctionName が message
という一般的な用語ではなく指定された場合、提供された名前は現在のハンドラの名前と同じでなければなりません。
Syntax:
pass handlerOrFunctionName
pass {the} message
例:
pass message
Pass ... and Continue
コマンド
振る舞い: pass
コマンドと同様に、現在のメッセージをメッセージパスの次のオブジェクトに渡しますが、メッセージが他の場所で処理された後に現在のハンドラが実行を続けることを可能にします。現在のハンドラは、メッセージがメッセージパスの後続のオブジェクトによって処理された後に実行を再開します。他のオブジェクトが返す任意の値は、pass ... and continue
コマンドの直後に the result
で利用可能です。pass ... and continue
コマンドを実行した後、そのメッセージを渡そうとする後続の試み(pass
コマンドのいずれかを使用して)は、メッセージが同じオブジェクトに二度配信され ることはないため、実際にはメッセージを渡すことはできません。
Syntax:
pass handlerOrFunctionName and continue
pass {the} message and continue
例:
pass message and continue
Pass ... Without Helping
コマンド
動作: メッセージを、メッセージパス中で助けられるオブジェクトの後にある次のオブジェクトに渡します。これは、ヘルパーで使用された場合、pass
コマンドとは異なります。本質的に、ヘルパーは「私はこのメッセージを助けることができません」と言っています。ヘルパーのヘルパーはメッセージを処理するチャンスが与えられませんが、メッセージは助けられるオブジェクトの後のヘルパーと、メッセージパスの後の他のオブジェクトに渡されます。このコマンドが実行されると、現在のハンドラは実行を停止します。
Syntax:
pass handlerOrFunctionName without helping
pass {the} message without helping
例:
pass message without helping
Pass Original Message To ...
コマンド
動作: pass original message to ...
を使用して、現在のメッセージを直接他のオブジェクトに渡します。これは、pass
コマンドの他の形式とは異なり、現在のメッセージをメッセージパスの次のオブジェクトに渡します。
この形式の pass
コマンドは、undeliveredMessage
ハンドラ内で使用することを目的としており、元の(未配信の)メッセージを他のオブジェクトに渡して処理することを試みます。そのオブジェクトがメッセージを処理すれば、それが終了となり、現在のハンドラの実行は終了します。他のオブジェクトがメッセージを処理しない場合、現在のハンドラの実行は続行します。このように、undeliveredMessage ハンドラは、元のメッセージを処理できる可能性がある1つまたは複数の他のオブジェクトに配信することを試みることができます。詳細は、未配信メッセージ を参照してください。and continue
が指定されている場合、メッセージが渡された後、現在のハンドラは実行を再開します。それが他のオブジェクトによって処理されたかどうかにかかわらず。
Syntax:
pass original message to object {and continue}
例:
pass original message to alterEgo
メッセージ情報
CallStack
関数
動作: callStack
関数は、現在の実行フレームに関する情報を提供するSenseTalkフレームオブジェクトのリストを返します。現在のハンドラがどのように呼び出されたかについての情報を得るために callStack()
を呼び出します。
Syntax:
the callStack
callStack()
例:
put property "Line" of the last item of the callStack into currentLine
MessageType
関数
動作: ハンドルされているメッセージの種類を示す値を返します。たとえば、"Command" または "Function" など。これを使用すると、ジェネリック(「to handle」)ハンドラが、それがどのように呼び出されたかによって異なるアクションを実行することができます。返される可能性のある他の値には、"GetProp" や "SetProp" が含まれます。
Syntax:
the messageType
messageType()
例:
if the messageType is "Function" then return theAnswer
パラメータと結果
パラメータの渡し方
パラメータの渡し方については、Parameters and Results ページを参照してください。
メッセージによって返される情報
関数メッセージ、そし て時々コマンドメッセージは、値を返します。関数メッセージによって返される値は、関数呼び出し表現の値になります。したがって、以下の例では、roundToNearest
関数メッセージによって返される値が monthlyPayTothePenny
変数に入れられる値となります:
put "roundToNearest(salary/12, 0.01)" into monthlyPayTothePenny
返される値は一つの値であることもありますし、場合によっては複数の値を含むリストやプロパティリストであることもあります。
結果
コマンドメッセージから値が返されると、その値は次の行で 結果
として利用できます。 結果
の値は各ステートメントで empty
にリセットされるため、特定の結果は次のステートメントでのみアクセス可能です。結果についての詳細は、結果関数 をご覧ください。