SenseTalkの変数
変数とは何ですか?
変数とは名前付きのコンテナです。それらは計算機の"メモリ"機能に似た値の保持者として機能します。最も単純な計算機とは異なり、一つの数値しか保持しない一つのメモリロケーションしか持たないものが多いのに対し、あなたは多くの値を一度に異なる変数に保存することができます。また、変数に保存される値は単一の数値に限定されることはなく、任意の大きさのデータが可能です。異なる変数を追跡するために、それぞれに名前が付けられています。
SenseTalkは次の3種類の変数を提供します:
ローカル変数、グローバル変数、ユニバーサル変数の名前は、文字またはアンダースコア _
で始まる必要があります。名前は任意の長さで、文字、数字、アンダースコア、および多くの非句読点特殊文字を含むことができます。すべての変数名は大文字と小文字を区別しません(大文字と小文字は同等に扱われます)。
いくつかの有効な変数名:
Total
_new_moon_
tree23
Ω
いくつかの無効な変数名:
3options -- 変数名は数字で始まることはできません
ToBe?OrNot -- 変数名は句読点やスペースを含むことはできません
ローカル変数
ローカル変数は最も一般的です。それらはスクリプト内の単一のハンドラのコンテキスト内で存在します。ローカル変数を作成するには、スクリプト内でそれに何かを入れるだけです。たとえば、コマンド put 5 into foo
は、既に存在しない場合はローカル変数 foo
を作成し、それに数値5を格納します。
ローカル変数は、それらが使用されているハンドラ(またはスクリプト)の外部からアクセスすることはできません。別のハンドラでの foo
への参照は、その他のハンドラにローカルな別の foo
になります。ローカル変数は一時的で、ハンドラの実行が終了するとその値は消えます。
to
、on
、または function
宣言でハンドラ名の後に宣言されたパラメータは、ローカル変数の特殊なタイプです。パラメータ変数は、ハンドラが実行を開始するときにはすでにメッセージの送信者によって渡された値を含むため、他のローカル変数と異なります。他のローカル変数は、ハンドラが実行を開始するときに初期値がありません。
値が割り当てられていないローカル変数(および特殊な事前定義値を持つものは除く、定数と事前定義変数を参照)は、その名前に評価されます。これは一部の状況で便利な、引用符なしのテキスト文字列リテラルの形式を提供しますが、後でその名前の変数に何かを格納することを選択した場合に混乱を招く可能性があります。一般的には、予期しない結果を避けるために、テキストリテラルの周りに常に引用符を使用することが最善です。
未定義の変数とStrictVariablesグローバルプロパティ
まだ値が割り当てられていないローカル変数は通常、引用符なしのリテラルとして扱われます—つまり、その値はその名前と同じです:
put Hello -- "Hello"を表示する
時に、この振る舞いが問題を引き起こすことがあります。例えば、スクリプトの後半部分で変数の名前を誤ってつづった場合や、以前に格納された値を持っていると期待した場合などです。このようなケースでスクリプトのデバッグを支援するため、または単により厳格なアプローチを好む場合、the strictVariables
グローバルプロパティを true に設定できます。このプロパティが設定されていると、明示的に宣言されていない変数や値が割り当てられていない変数へのアクセスを試みると、変数の名前を返す代わりに例外がスローされます:
put Bonjour into greeting -- "Bonjour"をgreeting変数に格納する
set the strictVariables to true
put Bonjour into greeting2 -- 例外をスローする
いくつかのローカル変数は事前定義された値を持っています。the strictVariables
プロパティはこれらの値の使用に影響しません—それらの変数に明示的に値を割り当てていなくても、それらを引き続き使用することができます(定数と事前定義変数を参照)。
グローバル変数
グローバル変数はプロジェクト内の任意のハンドラから参照することができます。ローカル変数とは異なり、グローバル変数は異なるハンドラ間でその値を保持します。ハンドラが呼ばれるたびにローカル変数が未定義の状態から始まるのに対し、グローバル変数は以前に割り当てられた値(同じハンドラによる以前の呼び出し、または別のハンドラによるもの)を持っている可能性があります。
グローバル変数を作成し使用するには、SenseTalkがそれらをローカル変数と区別できるように、それらが使用される各ハンドラ内でグローバルとして宣言する必要があります。これは global
キーワードを使用して行います。global
キーワードはコマンドのように行の先頭で使用でき、その後にはグローバルとして宣言される変数の名前のリストが続きます。このような宣言は、ハンドラ内でそれらの変数が他の用途で使用される前になされる必要があります。そのため、通常、グローバル宣言行をハンドラの始めに置くのが良い習慣です。次の例のように:
to doSomethingUniquely
global didItBefore -- グローバル変数を宣言する
if didItBefore is true then -- それを二度行うことは許されていない
answer "Can’t do it again!"
else
dotheThingToBeDone
put true into didItBefore
end if
end doSomethingUniquely
また、事前に宣言せずにグローバル変数を参照することも可能です。その方法は、単にその名前の前に global
キーワードを付けるだけです。このアプローチを使用すると、上記の例は次のように書き直すことができます:
to doSomethingUniquely
if global didItBefore is true then
-- それを二度行うことは許されていない
answer "Can’t do it again!"
else
dotheThingToBeDone
put true into global didItBefore
end if
end doSomethingUniquely
ローカル変数とは異なり、値が割り当てられていないグローバル変数とユニバーサル変数は単に空です—それらはその名前に評価されません。
グローバル変数は"グローバル"なので、プロジェクト内の任意のスクリプト内の任意のハンドラからアクセスすることができます。これは、異なるハンドラ間で情報を共有するための便利な手段を提供します。ただし、プロジェクトの異なる部分で異なる目的で同じグローバル変数名を使用しないよう注意を払う必要があります。
例えば、上記のdoSomethingUniquely
ハンドラを使用してアクションが二度実行されないようにした後、同じハンドラを別のスクリプトにコピー&ペースト(dotheThingToBeDone
行だけを変更)し、他のアクションも一度だけ実行するように制限すると、問題が発生します。両方のスクリプトが 同じグローバル変数(didItBefore
)を使用して、そのアクションがすでに実行されたかどうかを追跡しているため、最初にdoSomethingUniquely
ハンドラを呼び出すものが、他のものがアクションを全く実行できないようにします!
この問題を解決するためには、各ハンドラで異なるグローバル変数を使用するように、変数名(didSomethingBefore
、didTheOtherThingBefore
など)を変更するか、二つのケースを区別する他の方法を考える必要があります。
GlobalNames関数
globalNames()
関数(またはthe globalNames
)は、値が割り当てられているすべてのグローバル変数の名前のリストを取得するために使用できます。
ユニバーサル変数
ユニバーサル変数は、グローバル変数とまったく同じ方法で作成および使用されます。グローバル変数とユニバーサル変数の違いは、SenseTalkが実行されているホストアプリケーションによって定義されます。通常、ユニバーサル変数はグローバル変数よりも広範囲にわたるスコープを持ちます。例えば、グローバル変数は単一のプロジェクト内に存在できる一方、ユニバーサル変数は異なるプロジェクト間で共通の情報を共有することができます。また、Eggplant Functionalの場合、グローバル変数は各スクリプトの実行後にその値を リセットすることができますが、ユニバーサル変数はセッション全体でその値を保持します。
ユニバーサル変数は、universal
キーワードを使用して宣言する必要があります。これは、それらが使用されている各ハンドラ内で、それらが参照される前に何らかの宣言行にuniversal
キーワードを使用するか、任意の式内で変数名の直前にuniversal
キーワードを即座に使用することによって、グローバル変数の場合と全く同じ方法で行われます。
UniversalNames関数
universalNames()
関数(またはthe universalNames
)は、値が割り当てられているすべてのユニバーサル変数の名前のリストを取得するために使用できます。次の例は、すべてのユニバーサル変数の名前と値を表示します:
repeat with each item of the universalNames
put "Universal " & it & " is " & value("universal " & it)
end repeat