2016-09-12T12:20:49+09:00

AppleScriptObjC を使っているとスクリプトエディタでスクリプトを保存できなくなるエラーの回避法

次のように、スクリプトの(暗黙の)run ハンドラ内で、Objective-C のオブジェクトを変数に入れているスクリプトがあるとします。このスクリプトを実行後に保存しようとすると、エラーが発生します。

use AppleScript version "2.4"
use framework "Foundation"

set str to current application's NSString's stringWithString:"abcd"

なぜエラーが発生するかというと、

  1. (暗黙の)run ハンドラ内の変数は、property です。トップレベルで宣言されていなくても、自動的に作られます。
  2. AppleScript の property の現在値はスクリプトファイルに保存される/できるという性質があります。
  3. Objective-C のオブジェクトはポインターすなわちメモリのアドレスであり、保存しても次回の実行時には意味が無い値となります。
  4. したがって、Objective-C のオブジェクトは保存が制限されていると思われます。

と解釈できます。

とにかく、property に Objective-C オブジェクトを入れているのがいけないのだから、実行終了後に破棄されるローカル変数に入れるようにすればよい。この場合、エレガントな対応は次の二つ。

明示的なローカル変数宣言を行う

なかなか、利用することは少ないのだけど、AppleScript にはローカル変数であることを宣言する構文がある。次のように 変数「str」を明示的にローカル変数にしてしまえば、変数「str」は property ではなくなり、スクリプトの保存時にエラーは発生しなくなくなる。

use AppleScript version "2.4"
use framework "Foundation"

local str
set str to current application's NSString's stringWithString:"abcd"

でも、もっといい方法がある。明示的なローカル変数宣言は、変数が増えてくると大変じゃん。いちいち、local ~ なんて書くのはめんどくさいじゃん。

ユーザー定義ハンドラ内で実行する

ユーザー定義ハンドラ無いですべての Objective-C オブジェクトを扱うようにすれば、すべての問題が解決する。ハンドラ内の変数はデフォルトでローカル変数だからね。いちいち、local ~ という文を書かなくてもよろしい。

use AppleScript version "2.4"
use framework "Foundation"

on main()
set str to current application's NSString's stringWithString:"abcd"
end main

main()

以前、「私の run ハンドラ」という文章を書いたことがある。run ハンドラ内の変数の不用意な保存を避けるために、run ハンドラ内では、ハンドラの呼び出しとエラー処理だけを行いましょう、という内容です。今回の結論も似たような形になった。合わせてご一読ください。