頻繁に使用する文の幾つかは、スクリプトを書くのを楽にするために、省略できるようになっています。省略されているが、実は裏で処理されている文を「暗黙の…」といいます。所謂「暗黙の了解」というやつです。
逆に、暗黙に処理される文をきちんと書く事を「明示」と表現します。
大抵はスクリプトが省略できて便利なのですが、たまに予想外の働きをしていることがありますから、どのように暗黙の定義が行われているか知っておくのもいいでしょう。
「省略できる用語」も参照して下さい。
ハンドラの最後にある文が返す値がハンドラの返り値になります。つまり暗黙のreturn文があるわけです。
制御構造によって飛ばしている場合などは、最後にresultに設定した文がどこにあるのか分りにくくなってしまうので、そのような場合は特に明示的にreturn文を書いた方がいいでしょう。
x()
on x()
if true then
"この値が帰っていく"
else
"ここに何が書いてあっても関係無し"
end if
end x
ちょっと意外なところとしては、スクリプトオブジェクトを定義する場合も使えたりします。
set ScrObj to makeObj() -- スクリプトオブジェクトxが定義される
on makeObj()
script X
end script
end makeObj
システム変数のresultに値を代入するのがget命令ですが、ほとんどの場合は自動的に処理が行われるので、get命令を記述する必要はありません。
ただし、アプリケーションの方でget命令を定義してある場合、明示的にget命令を書いた方が、確実に素早く値を取り出す事ができる場合があります。
上手く値が取りだせない場合は、オブジェクトの属性の前にget命令を書いてみるといいかもしれません。その際、get命令は行の最初に書く必要は無く、文の中に埋め込んでいても構いません。
tell application "QuoEdit"
-- ここではgetを使っているが、無くても勿論動作する。
if get auto indent then
display dialog "オートインデントは真です。"
else
display dialog "オートインデントは偽です。"
end if
end tell
宣言の無い変数は、local文による暗黙の局所変数宣言されているとされます。
ところが、トップレベルのrunハンドラの変数は、宣言しないとglobalで宣言されているものとして扱われます。
他のハンドラの大域変数とぶつかって、原因不明のバグを呼び込むことがあります。
また、大域変数はスクリプトが終了したときに記録されるので、スクリプトサイズがいつのまにか膨らんで、突如としてスクリプトが起動しなくなったりもします。
なお、トップレベルで無い他のスクリプトオブジェクトのrunハンドラの変数は局所変数です。
詳しくは「大域変数の有効範囲」を参照して下さい。
-- local a -- このように明示的にlocal宣言を行うとよい
set a to "局所の筈なのに"
x()
display dialog a
on x()
global a
set a to "何故か大域です"
end X
どのハンドラにも属していない文はrunハンドラの文になります。これを暗黙のrunハンドラと言います。
暗黙のrunハンドラの場合は、間に他のハンドラやスクリプトオブジェクトの定義を含んでも動作します。
また、大域変数の宣言がrunハンドラ内か、トップレベルでの宣言なのかとか、属性の宣言がどこにあるのかとか、非常に分かりにくいスクリプトになる可能性があります。
少なくとも、大きめのスクリプトになったら、明示的にrunハンドラを書くのがいいでしょうし、とにかく必ずrunハンドラは明示するというのも安全な方法です。
display dialog "Step 1"
on x()
end x
display dialog "Step 2"
script Y
end script
display dialog "Step 3" & z -- 属性は後ろで宣言していてもOKだけど
property z : " and z"
display dialog "Step 4" & z -- & xx --大域変数は前で宣言しないと使えない
global xx
set xx to 10
tell applicationの後にlaunch命令かrun命令以外が書かれてかつアプリケーションが起動していない場合、最初の命令が実行される前にrun命令が実行されます。これを暗黙のrun命令といいます。アプリケーションによっては、最初にrun命令が書かれている場合、二度実行されてしまう事があります。アプレットは起動時に二度run命令が実行されてしまう代表的なアプリケーションです。
次のスクリプトは、何故か起動時に二回runされてしまう(大抵のアプリケーションは1回しか実行されないので気にする必要は無いのですが)
tell application "Jedit3"
run
end tell
そのようなアプリケーションの場合は、launch命令をrun命令の前に置きます。
launch命令に暗黙のrun命令を実行せずにアプリケーションを起動する働きがあるからです。
tell application "Jedit3"
launch
run
end tell
AppleScriptはオブジェクトや値を、値を取り出す必要のある場所に指定すると「contents of」があるものとして処理するのが普通です。
特に参照を利用したい場合は、参照を代入したいのに、内容の方が代入されてしまうので、確実に「a reference to」演算子で参照として代入する必要があります。
set org to "文字列"
set x to a reference to org
-- 「contents of」を付けても付けなくても結果は同じ
display dialog x
display dialog contents of x
逆にオブジェクトや変数を値を代入される場所に指定した場合、「contents of」が必要な場合確実につける必要があります。
特に参照を利用したい場合は、参照を代入したいのに、内容の方が代入されてしまうので、確実に「a reference to」演算子で参照として代入する必要があります。
set org to 1
set x to a reference to org
set contents of x to x +1
display dialog contents of org -- 1から2に増える
set x to x +1
display dialog contents of org -- 2のまま
これは多少、暗黙の表現とは違うかもしれませんが、実際上は暗黙の表現として働きます。
値のクラスであるstringの別名であるtextは複数形もtextです、textsではありません。
ですから、itemあたりだとevery itemとitemsが等しい表現であるように、every textとtextが等しい表現になります。結果、あたかもeveryを省略したかのように見える、というわけです。
この辺りの仕組みは全要素参照をご覧ください。
AppleScriptは結構大雑把に違う種類の値を置いても適当に変換してくれます。
詳しくは、暗黙の型変換を参照して下さい。