メッセージ

オブジェクトは、メッセージを受け取る場合にのみアクティビティを実行します。オブジェクトはメッセージを自分に送ることができます。または、別のオブジェクトや、そのスクリプトが存在する環境からメッセージを受信する場合もあります。例えば、コマンドラインからスクリプトが呼び出される場合は、スクリプトの名前に基づいてメッセージが送信され、これによりスクリプトが実行されます。

まず第一に、メッセージがオブジェクトに送信される際にオブジェクトはそのメッセージを受信して処理できるか、または無視できるかを把握する必要があります。メッセージとその送信方法を確認するために読み進めてください。

注意:次のハンドラセクションにおいて、オブジェクトがメッセージを受信、処理する方法を確認できます。

メッセージの送信

スクリプトの実行中は、スクリプトがそのコマンドを実行するのに伴い、絶えずメッセージが送信されます。メッセージは常に1つのワードであり、最も簡単なメッセージ送信ステートメントは、送信するメッセージの名前である一語のコマンドとなります。例えば、以下のスクリプトの2行目は、メッセージ「greetTheUser」を送信します。

put "Hello, World!"

greetTheUser

put farewellMessage()

このスクリプトでは、1行目と3行目のputコマンドもメッセージを送信します。実際には、いくつかの基礎的なSenseTalk制御構造の例外を除き、スクリプト内のほとんどすべてのコマンドがメッセージを送信します。上記の「farewellMessage()」関数の呼び出しのように、関数呼び出しもメッセージを送信します。

コマンドメッセージと関数メッセージ

実際に、SenseTalkは2つの異なるタイプのメッセージを送信します。コマンドメッセージは、上記の例における「greetTheUser」のように、コマンドによって送信されます。関数メッセージは、上記の例における「farewellMessage」のように、関数呼び出しによって送信されます。これら2つのタイプのメッセージは、メッセージを受け取るハンドラのタイプを除いて全く同じです。(下記のハンドラのセクションを参照)

メッセージの送信先は?

上述したように、メッセージはオブジェクト同士が対話できるようにするために使用されます。そのため、上記の「greetTheUser」メッセージや「put」メッセージの送信先が気になる方がいらっしゃるかもしれません。これらのメッセージを受信するオブジェクトとは?その答えは非常にシンプルですが、幾分びっくりするものかもしれません。これらのコマンドを含むオブジェクトが、自分にメッセージを送信するのです!

一見すると、オブジェクトが自分にメッセージを送ることにはあまり意味がないように思えるかもしれません。しかし実際には、そのオブジェクトに処理されないメッセージは、他のオブジェクトによって可能な処理や、究極的にはSenseTalkの内蔵コマンドや関数によって可能な処理のために渡されます。

必要に応じて、その他の特定のオブジェクトに直接メッセージを送信することも可能です。これは、sendコマンドやrunコマンド、角括弧メッセージ構文(次のセクションで説明)、または統合プロパティおよび関数のアクセスコール(本セクションの後半で詳しく説明)を利用して実行できます。

get investor's balance("Checking")

-- 投資家に「balance」を送ります

add paycheck.netIncome() to it

-- 給与に「netIncome」メッセージを送ります

パラメータと結果

それぞれのメッセージは一語(メッセージ名)で特定されますが、「パラメータ」形式の情報を追加することも可能です。コマンドput “Hello, World!”は、「put」メッセージに随伴する単一パラメータとして、文字列「Hello, World!」を送信します。2つ以上のパラメータを送るには、以下のようにパラメータ間にコンマを使用して表記します。

WaitFor 15, "BigBlueButon"

関数呼び出しメッセージにパラメータを追加するには、関数名の後ろの丸括弧の中に表記します。

put "roundToNearest(salary/12, 0.01) into monthlyPayTothePenny

便宜上、パラメータとして単一のプロパティリストを渡す場合は、丸括弧でプロパティリストを囲む必要はありません。これは、名前ごとに受け渡しパラメータの効果を与えます。

addToInventory item:"candles", quantity:6,color"Blue"

set article to fetchClipping(author:"Lewis", title:"Lost")

これらのパラメータは、これらの形式のうちの1つが使用される際に、単一のプロパティリストとして実際に渡されます。

単一呼び出しにおいては、名前付きパラメータが最後に来ることを条件に、名前付きパラメータと名前なしパラメータとを組み合わせて使用できます。名前付きパラメータは、最後のパラメータとして渡されるプロパティリストとして送信されます。

addAtPosition 23, item:"paper", quantity:500, color"White"

値のリストは、リストの後にas parametersと特定することにより、個々のパラメータとして渡すことができます。

calculateVariance bigListOfNumbers as parameters

これは特に、現在のハンドラが受信したパラメータのリストを渡す際に役立ちます。

return otherFunction(parameterList() as parameters)

メッセージが返す情報

関数メッセージは1つの値を返します。また、時にはコマンドメッセージが返すこともあります。関数メッセージが返す値は、関数呼び出し式の値となります。そのため、最後の例において、「roundToNearest」関数メッセージが返す値は、monthlyPayTothePenny変数に入れられる値となります。返される値は単一の値か、またはいくつかの場面では、複数の値を含むリストまたはプロパティリストとなります。

結果

ある値がコマンドメッセージから返されたら、 その値をresultとしてそれ以降の行で利用できます。resultの値はステートメントごとにemptyにリセットにされるため、得られた結果にはその次のステートメントでのみアクセスできます。返された値が例外オブジェクト(objectTypeが「exception」のプロパティリスト)の場合は、呼び出し元はthrowExceptionResultsグローバルプロパティがTrueに設定されている場合に例外を投げます。

メッセージパス

メッセージを1つのオブジェクトに送信すると、メッセージは複数の異なるオブジェクトを辿るパスを進みます。メッセージが進むパスに沿う各オブジェクトには、メッセージを処理する機会が与えられます。オブジェクトにそのメッセージ用のハンドラが含まれる場合は、そのハンドラ内の指示が実行されます。そうでない場合は、メッセージを処理するオブジェクトが見つかるまで、メッセージはパスに沿うその他のオブジェクトに順番に提供されます。

通常は、メッセージがオブジェクトに処理されて終了となります。ただし、いくつかの場面では、オブジェクトのハンドラがメッセージをパスに沿って渡すことを選択し、その他のオブジェクトが同じメッセージを処理できるようにする場合があります(メッセージの操作におけるpassコマンドを参照)。

BackscriptsとFrontScripts

広い視野で見ると、メッセージの送信先のオブジェクト(ターゲットオブジェクトという)に加えて、メッセージパスには、ターゲットオブジェクトとそのヘルパーの前後のその他のオブジェクトも含まれる場合があります。これらはfrontScriptsbackScripts内のオブジェクトに加えて、ホストアプリケーションに含まれる追加のオブジェクトで構成されます。

FrontScriptsはめったに使用されないグローバルプロパティであり、ターゲットオブジェクトにメッセージが提供されるよりも前にメッセージを処理する機会が与えられるオブジェクトのリストが含まれます。これにより、メッセージを傍受する機会と、任意のオブジェクトの挙動を上書きする潜在的機会がこれらのオブジェクトに与えられます。本プロパティが要求されることはほとんどありませんが、メッセージパスに沿って渡す前のメッセージの記録などのように、タスクに役立つ場合があります。

backScriptsはグローバルプロパティであり、ターゲットオブジェクトがメッセージを処理しなかった場合に、ターゲットオブジェクトの後でメッセージを処理する機会を与えられるオブジェクトのリストが含まれます。このため、backScriptsにオブジェクト(ライブラリまたはスクリプト)を挿入することで、スクリプトによるオブジェクトのハンドラの利用が可能になります。その一方で、backScript挙動を上書きするために個々のスクリプトがそれ自身のハンドラを提供する能力は保たれます。

backScriptsは、backScripts内のオブジェクトの追加と削除を簡素化する2つの特別なコマンドを提供する非常に役に立つメカニズムです。start using <object> コマンドは、backScriptsにスクリプトやその他のオブジェクトを挿入します。stop using <object>構文は、事前にbackScriptsに挿入したライブラリまたはスクリプトを除去します。これらのコマンドは、insert <object> into the backScriptsコマンドと、remove <object> from the backScriptsコマンドと等価ですが、より簡潔で判読しやすいものとなっています。

ヘルパー

メッセージがパスに沿う各オブジェクトに渡された後でそのオブジェクトのスクリプトをチェックし、そのメッセージ向けのハンドラが含まれていないか確認します。ハンドラが含まれている場合は、そのハンドラが実行されます。ハンドラが含まれていない場合は、そのメッセージは各オブジェクトのヘルパーにも順番に渡され、そのメッセージ向けのハンドラが含まれているか確認されます。ヘルパーの1つに適切なハンドラが含まれるかどうかをチェックする際は、ヘルパーのリストのほかに、それらのヘルパー(存在する場合)なども確認されます。すべてのヘルパーがチェックされて初めて、メッセージはメッセージパスに沿う次のオブジェクト渡されます。

backScriptsリスト内のオブジェクトは、メッセージパスにおけるその他のオブジェクトによって処理されないメッセージのみを受け取ります。これらは一般的に、多くの異なるオブジェクトが必要とする基本的機能を提供するのに使用されます。frontScriptsリスト内のオブジェクトは、ターゲットオブジェクトに達する前のメッセージを傍受、処理する機会を与えられます。本機能はめったに使用されませんが、特定の状況で威力を発揮する場合があります。

ホストアプリケーション

メッセージ受け渡しパス内のすべてのオブジェクト(およびそのヘルパー)がメッセージを処理する機会を与えられた後は、メッセージはホストアプリケーションとSenseTalkに配信されます。メッセージが内蔵コマンドまたは関数に相当する場合は、そのコマンドまたは関数が処理されます。一部のメッセージはSenseTalkによって認識されるものの無視されます。メッセージがSenseTalkによって認識・処理もされず、認識・無視もされない場合は、ホストアプリケーションはそのメッセージと同じ名前のスクリプトファイルを検索します。一般的に、呼び出しスクリプトが存在するのと同じフォルダが少なくとも検索され、これに加えて、その他のフォルダも検索される場合があります。メッセージを処理するためのスクリプトファイルが見つからない場合はエラーが発生します。

フルメッセージの受け渡しパス

全体として、メッセージが(ターゲットオブジェクトと呼ばれる)オブジェクトに送信される場合は、そのメッセージのフルパスは、以下のオブジェクトにこの順序どおりに送信されます。

  • frontScripts内に挿入されている順序どおりのオブジェクト(直近で前方に挿入された、最後にメッセージを受け取るオブジェクトを含む)とそのヘルパー

  • ターゲットオブジェクトとそのヘルパー

  • BackScripts内のオブジェクト(直近で後方に挿入された、最後にメッセージを受け取るオブジェクトを含む)とそのヘルパー

  • ホストアプリケーションとSenseTalk

  • ホストアプリケーションが確認するフォルダ内のその他のスクリプトファイル

メッセージ用のハンドラが見つかるたびに、そのハンドラが実行されます。このようなハンドラがメッセージを渡さない場合は、処理されたとみなされてこれ以上先には進みません。ただし、ハンドラはpassコマンド(またはこれと同等のもの)を利用してメッセージを渡すことを選択する場合があります。このような場合は、メッセージは処理されていなくてもメッセージ受け渡しパスに沿って進み、パス内の後ろのオブジェクトがそのメッセージを受け取る機会を与えられます。

技術トピック

構文insert object into back

insert object into the backScripts

start using object

remove object from back

stop using object

insert object into front

insert object into the frontScripts

remove object from front

ターゲット

メッセージはメッセージパスに沿う複数の異なるオブジェクトのいずれかによって処理される可能性があるため、これらのオブジェクトはメッセージの送信先オブジェクトを探し出さなければならない場合があります。これがtargetの目的であり、これにより、そのターゲットオブジェクトが特定されます。例えば、backScriptsに挿入されるオブジェクトは、以下のように、実行されるたびにカウンタの値を増加させるincrementAccessCountハンドラを有する場合があります。

on incrementAccessCount

add 1 to the accessCount of the target

end incrementAccessCount

ここでは、それ自身のaccessCountプロパティ内で単一のカウンタを維持するのではなく、incrementAccessCountメッセージを受け取ったあらゆるオブジェクトのaccessCountプロパティが更新されます。

 

This topic was last updated on 2月 01, 2019, at 11:13:23 午前.

Eggplant icon Eggplant.io | Documentation Home | User Forums | Support | Copyright © 2019 Eggplant