SenseTalkにおける変数
変数とは、名前付きのコンテナのことをいいます。 これは、計算機の「記憶」機能と同じように、値の入れ物として作用します。 ほとんどのシンプルな計算機では、数を1つ保持するための記憶場所が1つだけ存在しますが、変数の場合は、多くの値を異なる変数に一度に格納できます。 また、変数に格納する値は1つの数に制限されず、大量のデータを自在に格納できます。 異なる変数を見失わないようにするために、各変数には名前が付けられます。
ローカル、グローバル、およびユニバーサル変数の名前は、文字または下線符号(_)で始まる必要があります。 名前は任意の長さとすることができ、文字、数字および下線符号を含むことができます。 すべての変数名は、大文字と小文字を区別しません(大文字と小文字は同じものとして処理されます)。
ローカル変数
ローカル変数は、最もよく使用される変数です。 スクリプト内で、本変数は単一のハンドラのコンテキスト内に存在します。 ローカル変数は、スクリプト内の変数に値を入れるだけで作成できます。 例えば、put 5 into fooというコマンドにより、ローカル変数fooが作成され(存在していなかった場合)、数字の5がこの中に入れられます。
ローカル変数を使用するハンドラ(またはスクリプト)外で、ローカル変数にアクセスすることはできません。 別のハンドラ内でfooを参照する場合は、そのハンドラに対してローカルである個別のfooを参照することになります。 ローカル変数は一時的なものであるため、ハンドラが実行を終了する際にその値は消去されます。
on宣言またはfunction宣言において、ハンドラ名の後で宣言されるパラメータは、特別な種類のローカル変数です。 ハンドラの実行開始時にメッセージの送り元から渡された値が既に組み込まれているという点で、パラメータ変数はその他のローカル変数とは異なります。 その他のローカル変数は、ハンドラの実行開始時に初期値を保持しません。
未定義の変数とthe StrictVariablesグローバルプロパティ
値を割り当てられていないローカル変数は、通常、引用符なしのリテラルとして処理されます。言い換えれば、その値は名前と同じになります。
put Hello -- 「Hello」と表示されます
スクリプト後半で変数の名前のスペルをうっかり間違えてしまい、その変数には事前に格納されている値が存在すると予想される場合などに、この挙動がトラブルにつながる可能性があります。 このような場合にスクリプトのデバッグを手助けするために、あるいは単により厳格なアプローチを好む場合に、the strictVariablesグローバルプロパティをtrueに設定することができます。 本プロパティを設定すると、明示的に宣言されていない、または値が割り当てら得ていない変数にアクセスしようとすると、変数の名前が返されるのではなく、例外が投げられます。
put Bonjour into greeting -- 変数greeting内に「Bonjour」が格納されます
set the strictVariables to true
put Bonjour into greeting2 -- 例外が投げられます
グローバル変数
グローバル変数は、プロジェクト内の任意のハンドラから参照できます。 ローカル変数とは違い、グローバル変数は異なるハンドラ間でその値を保持します。 ローカル変数は、ハンドラを呼び出す度にハンドラの先頭で未定義である一方、グローバル変数は、(その前の呼び出し時と)同じハンドラまたは異なるハンドラのいずれかによって事前に割り当てられた値を既に保持している場合があります。
グローバル変数を作成し、使用するには、本変数を使用する各ハンドラ内でグローバルとして宣言し、SenseTalkがローカル変数と区別できるようにする必要があります。 これは、globalキーワードを使用して実行します。 globalキーワードは、コマンドと同様に行の先頭で使用でき、その後にグローバルとして宣言される変数の名前のリストが続きます。 この種の宣言は、ハンドラ内でその変数を使用する前に行う必要があります。 したがって、以下の例のように、通常はハンドラの先頭にグローバル宣言の行を置くことが推奨されます。
to doSomethingUniquely
global didItBefore -- グローバル変数を宣言します
if didItBefore is true then -- 2度実行できないようにします
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
-- 2度実行できないようにします
answer "Can’t do it again!"
else
dotheThingToBeDone
put true into global didItBefore
end if
end doSomethingUniquely
グローバル変数は「グローバル」であるため、本変数には、プロジェクト内における任意のスクリプトの任意のハンドラからアクセスできます。 これにより、異なるハンドラ間で情報を共有するための便利な手段が提供されます。 ただし、プロジェクトの様々な部分における異なる目的のために、同じグローバル変数名を使用しないように注意する必要があります。
例えば、上記のようにアクションが2度実行されないようにするためにdoSomethingUniquelyハンドラを使用し、(dotheThingToBeDone行のみが異なる)別のスクリプトに同じハンドラをコピー&ペーストしてその他のアクションの実行も1度に制限されるようにすると、問題が生じる可能性があります。 どちらのスクリプトも同じグローバル変数(didItBefore)を使用してアクションが実行されたかどうかを追跡することになるため、doSomethingUniquelyハンドラを呼び出す最初のスクリプトにより、もう一方のスクリプトによるアクションの実行が妨げられる結果となります。
この問題を解決するには、変数名を変更したり(didSomethingBefore、didTheOtherThingBeforeなど)、これらを区別する何らかの手段を利用したりして、ハンドラごとに異なるグローバル変数を使用する必要があります。
GlobalNames関数
globalNames()関数(またはglobalNames)は、既に値を割り当てられているすべてのグローバル変数の名前のリストを入手するのに使用できます。
ユニバーサル変数
ユニバーサル変数は、個別の宣言行で(本変数を使用する各ハンドラ内で参照する前に)、または任意の式内の変数名の直前で、グローバル変数と全く同じようにuniversalキーワードを使用して宣言する必要があります。
UniversalNames関数
universalNames()関数(またはuniversalNames)を使用すると、既に値を割り当てられているすべてのユニバーサル変数の名前のリストを入手できます。 以下の例では、すべてのユニバーサル変数の名前と値が表示されます。
repeat with each item of the universalNames
put "Universal " & it & " is " & value("universal " & it)
end repeat
変数の種類のまとめ
要約すれば、スクリプト内で使用可能な変数には、異なる3つのタイプが存在します。
- グローバル変数とユニバーサル変数は、それらを使用するハンドラごとに宣言するするか、それらを使用するたびに単語globalまたはuniversalを前に置く必要があります。
- ハンドラ内で単語globalまたはuniversalが前に置かれていない未宣言の変数は、そのハンドラに対してローカルとなります。
- ローカル変数は単一のハンドラの1回の実行に限って値を保持し、そのハンドラの実行が終了すると値は破棄されます。
- グローバル変数は複数のハンドラ間で維持される値を保持します。 本変数は実行の終了時に破棄されます。
- ユニバーサル変数はグローバル変数と類似していますが、ホストアプリケーションで定義されるように、通常はより大きな規模で存在します。 例えば、eggPlant Functionalでは、ユニバーサル変数は、複数のハンドラと複数の実行にわたって維持される値を保持します。 これらはeggPlant Functionalを終了する際に破棄されます。
これら3種類の変数はすべて異なります(すなわち、同じ名前で異なる値を持つローカル変数、グローバル変数およびユニバーサル変数が一度に存在できます)。
変数の削除
変数は、変数に値を割り当てることで自動的に作成されます。 また、変数はdelete variableコマンドまたはこのいずれかのバリアントを使用することで削除できます。
例:
delete variable holder -- ローカル変数「holder」を再び未定義にします
例:
delete local password
例:
delete global accountNumber
例:
delete universal pendingTasks
変数内のメタデータ
一部のケースでは、変数には、変数に格納される通常の値(データ)のほかに、追加情報(メタデータとも呼ばれる)が組み込まれる場合があります。 例えば、変数が日付または時間値を保持する場合は、変数に格納される実際のデータ(値)は、ある瞬間を特定する数値となります。 時間値のほかに、変数はフォーマットも保持し、これにより、値をユーザーに提示する方法や、値がテキストとして要求されている場合の表示方法が指定されます(SenseTalkにおける日付および時間値を参照)。
別の例として、変数がリストを保持する場合は、変数に含まれる値のリストは、コンテナのデータ(コンテンツ)となります。 この場合、メタデータはcurrentIndex値となり、リストをイテレータとして使用できるようになります(範囲、イテレータおよびEach式を参照)。
このような場合に、変数のデータコンテンツに加えて、SenseTalkはメタデータを変数のプロパティとしてスクリプトにアクセスできるようにします。
put the date into currentDate
put currentDate -- 10/22/10
put currentDate's format -- %m/%d/%y
put "%Y" into the last two characters of currentDate's format
put currentDate -- 10/22/2010