オブジェクト
SenseTalkは、プログラミングの複雑で奥深い詳細を習得するための長年の学習なしに、人々が自分自身のソフトウェアを作成できるように設計されました。このドキュメンテーションの早いセクションで提供される情報は、SenseTalkスクリプトを主にあなたがコンピュータに何をしたいのかを伝える簡単なステートメントのリストとして焦点を当てています。多くの人々にとって、その基本的なスクリプト作成のアプローチは彼らのニーズに十分でしょう。
ただ少しでも多くを学びたいと考える人々のために、SenseTalkのオブジェクトモデルは、その複雑さを大幅に増加させることなく、はるかに豊かな環境を提供します。
ここで説明する情報は、SenseTalkのモジュラー構造の概要を提供し、あなたが自分自身のオブジェクト指向のSenseTalkソフトウェアを書く方法を学び進めるにつれて親しむことを望むキーコンセプトと用語を紹介します。
舞台の設定
SenseTalkは"スクリプト"言語です。あなたはシス テムの異なる要素が何をするのかを説明するスクリプトを書くことでSenseTalkソフトウェアを作成します。SenseTalkでこれを行う通常の方法は、システムのアクターとなるいくつかの異なる“オブジェクト”を作成することです。各オブジェクトは、システム内で何をするのかを語る自身のスクリプトを持っています。このモジュラーなアプローチを採ることで、各スクリプトは比較的短く、自己完結型にすることができ、これにより複雑なシステムでも比較的簡単に扱うことができます。
システム内のオブジェクトは、メッセージの送受信によって相互作用します。オブジェクトは、そのメッセージのハンドラがある場合にメッセージを応答します。スクリプトは一連のハンドラから成り、そのオブジェクトが応答する各メッセージに対して一つずつあります。その他のメッセージはオブジェクトによって無視されます。
一つのSenseTalkオブジェクトは他のものを助けることができます。似たような振る舞いや能力を持つ必要があるいくつかのオブジェクトがある場合、共有される振る舞いと能力を具現化するヘルパーオブジェクトを作成することができます。他の各オブジェクトはヘルパーオブジェクトによって助けられることができ、それぞれが自身のスクリプトにそれらの振る舞いを定義する必要を排除します。これにより、あなたの時間と労力を大幅に節約することができます。また、ヘルパーオブジェクトのスクリプトを単純に変更することで振る舞いを更新することが簡単になります。その他のすべてのオブジェクトはその変更された振る舞いを“継承”することになります。
他のオブジェ クト指向言語に詳しい人々のために注意すべき点は、SenseTalkはやや異なるということです。ほとんどの他の言語はオブジェクトの“クラス”を定義し、一般にそのクラス内のすべてのオブジェクトに対してクラスレベルで振る舞いを実装します。しかしSenseTalkでは、各個別のオブジェクトが自身のスクリプトを持っているため、独自のユニークな振る舞いを持つことができます。
SenseTalkにはクラスがなく、そのヘルパーはオブジェクトが他の任意の数のオブジェクトによって提供される機能を使用(または継承)することを可能にすることで、同様に豊かな一連の機能を提供します。この全オブジェクト(クラスレス)アプローチは、クラスベースのシステムよりもシンプルで、かつ多機能です。
オブジェクトの定義
SenseTalkはオブジェクト指向言語です。SenseTalkスクリプトはオブジェクトの振る舞いを説明します。ホスト環境によりますが、オブジェクトは直接操作および対話が可能な、画面上のボタンやイメージなど、目に見えるものであるかもしれません。またはそれは銀行口座や運動スケジュールを表現するなど、より抽象的なものであるかもしれません。
オブジェクトが視覚的なものを表現しているのか、純粋に概念的なものを表現しているのかにかかわらず、SenseTalkの世界のすべてのオブジェクトは共通の特性を共有しています。どのオブジェクトも属性(プロパティと呼ばれる)を持つことができ、そのオブジェクトにとって重要な情報を保存します。また、オブジェクトは、オブジェクトのスクリプトによって定義され、オブジェクトが何をできるかを定義する動作を持つこともあります。
コンピューター画面に表示される画像の場合、そのプロパティは、その高さと幅、画像自体を形成するすべてのドットの色などを含むことができます。人の連絡先情報を表すオブジェクトは、その名前、電話番号、郵送先住所などのプロパティを含みます。
そのスクリプトによって定義されたオブジェクトの動作は、画像を逆さまにする、メーリングリストの人にメールメッセージを送るなどのことを含むことができます。オブジェクトの他の「動作」は、そのプロパティに直接表されていないオブジェクトに関する情報を提供するなど、より受動的なものである場合があります。たとえば、人を表すオブジェクトは、その生年月日を保存するプロパティを含むことができます。オブジェクトのスクリプトは、現在の日付にアクセスし、その生年月日以降に経過した年数を計算することで、その人の年齢を提供できます。
プロパティリスト
プロパティリストは、そのキーで識別される値の集合として、前のセクションで説明されました。そこでは、プロパティリストは実際には単純なオブジェクトであると述べられていました。
プロパティリストは、主にプロパティのオブジェクトです。しかし、ヘルパーを割り当てたり、スクリプトプロパティを有効なスクリプトに設定したりすることで、プロパティリストに動作を追加することができます。詳細については、Helpersを参照してください。オブジジェクトのスクリプトを設定するには、1つ以上のハンドラのテキストをそのオブジェクトの「スクリプト」プロパティに保存します。
put {width:7,length:12} into myRect
set the script of myRect to {{
function area
return my width * my length
end area
}}
}}
スクリプトファイル
多くのSenseTalkスクリプト環境では、各スクリプトはディスク上のテキストファイルに保存されています。これらの環境では、各ファイルはSenseTalkオブジェクトであり、ファイルの内容はオブジェクトのスクリプトです。
スクリプトは、そのオブジェクトの動作を定義するSenseTalkコマンド(_ステートメント_とも呼ばれます)のシーケンスで構成されています。ここに最も簡単で短い完全なSenseTalkスクリプトを示します:
put "Hello, World!"
スクリプトファイルは、主に動作のオブジェクトです。上記のスクリプトは非常に単純なオブジェクトを構成し、スクリプトが実行されるときに呼び出される単一の動作を持っています:「Hello, World!」という言葉を表示します。
プロパティ宣言
動作に加えて、スクリプトファイルには必要に応じてプロパティ宣言も含めることができます。スクリプトファイルをディスクからロードしてオブジェクトを作成するとき、そのスクリプトに含まれる任意のプロパティ宣言は、オブジェクトのプロパティの初期値を定義します。
プロパティ宣言は、どのハンドラの外部に配置することができます。それがスクリプトの最初のものであれば、初期ハンドラはそれの後に来ます。例えば、params
declarationの前に現れます。それ以外の場合、宣言されたハンドラがそうするように、初期ハンドラを終了します。ハンドラの操作についての詳細は、Handlers を参照してください。
同じスクリプトで複数のプロパティ宣言を持つことは可能ですが、単純さと混乱を避けるために、一つだけを使用することを推奨します。
構文:
プロパティ
propertyKey1 : value1 ,
{propertyKey2 : value2} ...
end Properties
例:
このプロパティ宣言は、オブジェクトの5つのプロパティを定義し、それらに初期値を割り当てます。スペースや特殊文字を含む値は、name
とbirthDate
プロパティで示されているように、引用符で囲む必要があります。単純な値には引用符が必要ありませんが、必要に応じて引用符を付けることもできます。いくつかのプロパティには、helpers
プロパティで示されているように、値のリストが割り当てられます。
Properties
name: "Charlie Brown",
birthDate:"May 14, 1942",
hairColor: brown,
numberOfSiblings:1,
helpers: ["Linus", "Lucy"]
end properties
スクリプトフォルダ
フォルダもまたSenseTalkオブジェクトとして機能します。フォルダをオブジェクトとして扱うとき、フォルダ内の各スクリプトファイルはそのオブジェクトのハンドラとして扱われます。"_initialHandler_"という特殊な名前のスクリプトがそのフォルダ内に存在する場合、それはフォルダオブジェクトの初期ハンドラとしてロードされ、その スクリプト内で定義されたプロパティはフォルダオブジェクトの初期プロパティ値として使用されます。
オブジェクトの使用
プロパティリストの作成
シンプルなプロパティリスト(プロパティはあるがハンドラはないオブジェクト)は、ここに示されている形式でそのプロパティと値をリストアップするだけで作成できます。
put {x:44, y:108, z:-19} into point2
シンプルなオブジェクトの作成
オブジェクトは他のオブジェクトによって助けられることができます(ヘルパーはこのセクションの後半で詳しく説明されています):
put {name:"Hank", age:47} helped by parent,actor into person
初期化されたオブジェクトの作成
初期化済みのオブジェクトは、new object
表現で作成できます:
put new object with {width:14, length:9} into dimensions
ここで示した例のように、new object
を使用してオブジェクトを作成すると、結果は基本的には前に示したシンプルなオブジェクトと同じです。唯一の違いは、新たに作成されたオブジェクトに"initialize"メッセージが送信されることです。もちろん、そのようなハンドラを持つヘルパーがない限り、そのメッセージに対応するハンドラは持っていません。このように、一つ以上のヘルパーとともにオブジェクトを作成することができます:
put new object with (partNum:1234) helped by part into aPart
プロトタイプオブジェクトでの作成
new object
表現を使用する一般的な方法は、「プロトタイプオ ブジェクト」を指定することです。以下の例で示すように:
set child to be a new Person with {name:"Penny", age:6}
この例では、Personはプロトタイプオブジェクトです。プロトタイプオブジェクトは(必要であれば)新しいオブジェクトの作成方法を完全に制御することができます(これがどのように動作するかの詳細は、このセクションの後半で説明されています)。ただし、通常の場合、新しいオブジェクトは、スクリプトで与えられたプロパティとプロトタイプからの他のプロパティのコピーを持ち、プロトタイプオブジェクトによって助けられます。ですので、Personオブジェクトが通常の振る舞いを上書きしない限り、上記の声明はこれと同等です:
set child to a new object with ({name:"Penny", age:6} adding properties of (object Person)) helped by Person
オブジェクトプロパティへのアクセス
オブジェクトのプロパティは、オブジェクトの後にドット(.
)またはアポストロフィ-S('s
)とプロパティ名を使用したり、オブジェクトの前にof
と続くプロパティ名を使用することで、いくつかの異なる方法でアクセスすることができます:
put {make:Yamaha, model:"U3", finish:"Walnut"} into piano
put "My piano is a " & piano.make && piano's model
put "It has a pretty " & finish of piano & "finish"
オブジェクトのプロパティはコンテナです。プロパティは追加、削除、またはその値を変更することができ、これについてはリストおよびプロパティリストで詳しく説明されています。
“Me”と“My”を使ってオブジェクト自身のプロパティにアクセスする
オブジェクトがそのスクリプト内から自身のプロパティにアクセスする必要があることは非常 に一般的です。自身を名前で参照するのではなく、me
とmy
という語を使用してこれを行うことができます:
put the age of me
if my name begins with "S" then return "Smilin' " & my name
未定義のプロパティとStrictPropertiesグローバルプロパティ
通常、オブジェクトの存在しないプロパティにアクセスすると、SenseTalkはそのプロパティの値として単にempty
を返します。たまに、プロパティ名を間違って綴った場合などに問題が生じることがあります。そのような場合にスクリプトのデバッグを支援するために、またはより厳格なアプローチを好む場合には、the strictProperties
グローバルプロパティをtrueに設定することができます。このプロパティが設定されていると、以前に設定されていないオブジェクトのプロパティにアクセスしようとすると例外がスローされます。
put a new object into emptyObj
put (property abc of emptyObj) is empty -- displays 'true'
set the strictProperties to true
put (property abc of emptyObj) is empty -- throws an exception
“Object”を使用してオブジェクトアクセスを確保する
ほとんどのコンテキストでは、SenseTalkはオブジェクトが必要なときを認識し、文字列値をスクリプトオブジェクトの名前として扱うことができます。しかし、意味が曖昧になることもあります。このような状況では、object
という語を使って値をオブジェクト名として扱うべきであることを示すことができます:
put "Person"'s greeting -- "Person"はテキストでありオブジェクトではないため、greeting関数が呼び出されます
put (object "Person")'s greeting -- "Person"をオブジェクト名として扱い、そのgreetingプロパティにアクセスします