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
変数タイプの要約
要約すると、スクリプトで使用できる変数には3つの異なるタイプがあります。
- グローバル変数とユニバーサル変数は、それらを使用する各ハ ンドラで宣言する必要があります。それ以外の場合、それらは
global
またはuniversal
という単語で先行する必要があります。 global
またはuniversal
の単語で先行されていない未宣言の変数は、そのハンドラにローカルです。- ローカル変数は、単一のハンドラの単一の実行内で値を持ち、ハンドラが実行を終了すると破棄されます。
- グローバル変数は、ハンドラ全体で持続する値を持ちます。それらは実行の終了時に破棄されます。
- ユニバーサル変数はグローバル変数と似ていますが、ホストアプリケーションによって定義される通常よりも大きなスコープを持つ傾向があります。例えば、Eggplant Functionalでは、ユニバーサル変数はハンドラ全体および実行全体で持続する値を持ちます。それらはEggplant Functionalが終了したときに破棄されます。
これら3つのタイプの変数はすべて異なります(つまり、同じ名前を持つが値が異なるローカル、グローバル、ユニバーサル変数をすべて同時に存在させることができます)。
事前定義変数
事前定義変数(定数と事前定義変数を参照)は、各ハンドラの開始時点で既に値があるローカル変数です。ハンドラ内でそれらに異なる値を割り当てて、そのハンドラ中で他の任意のローカル変数と同様に使用することができます。しかし、その値の割り当ては現在のハンドラにのみ適用され、他のハンドラではそれらは事前定義の値を持つままになります。
スイート変数は、Eggplant Functional内で事前定義の値がスイート内に永続的に保存されている特殊な事前定義変数です。詳細については、スイート変数の作成と使用を参照してください。
変数の削除
変数は、値を割り当てることで自動的に作成されます。delete variable
コマンドまたはそのバリエーションを使用して削除することもできます。
文法:
delete [variable | local | global | universal] variableName
例:
delete variable holder -- Makes local variable "holder" undefined again
例:
delete local password
例:
delete global accountNumber
例:
delete universal pendingTasks
変数のメタデータ
場合によっては、変数が通常の値(データ)に加えて追加の情報(メタデータとも呼ばれる)を含むことがあります。例えば、変数が日付または時間の値を保持している場合、変数に格納されている 実際のデータ(値)は、時間の瞬間を指定する数値です。この時間の値に加えて、変数は値がテキストとして要求されたときに値がユーザーに提示されるか、または代表される方法を指定するformat
を保持します(SenseTalkの日付と時間の値を参照)。
もう一つの例として、変数がリストを保持している場合、それが含む値のリストはコンテナのデータ(内容)です。この場合のメタデータは、リストをイテレータとして使用することを可能にするcurrentIndex
値です(範囲、イテレータ、Each表現を参照)。
これらの各ケースにおいて、SenseTalkは変数のデータの内容に加えて、メタデータをスクリプトが変数のプロパティとしてアクセスできるようにします:
put the date into currentDate
put currentDate --> 10/22/10
put currentDate's format --> [mo]/[da]/[yr]
put "[year]" into the last 4 characters of currentDate's format
put currentDate's format --> [mo]/[da]/[year]
put currentDate --> 10/22/2010