2016-02-24T13:53:23+09:00

システムによって実行するハンドラを切り替えるクールな AppleScript

OS のバージョンやインストールされているアプリケーションによって、実行する AppleScript のハンドラを切り替えたい事はしばしばあると思います。そのハンドラが1回のスクリプトの実行で1度だけ実行されるなら、愚直に if 文で条件分岐をすればよいですね。

しかし、何回も実行されるハンドラの場合、毎回 if 文を評価するのは無駄ですね。そこで、

という実装を紹介します。

条件判定は実行中に一回だけにする為に、ハンドラが自分自身を別のハンドラに置き換えるというテクニックを用います。

下の例では、say_hello ハンドラを実行すると、say_hello ハンドラを new_handler か old_handler に置き換えます。

ちなみに、トップレベルに定義されているハンドラの置き換えはしません。それをやると、スクリプト実行時に変更が保存されてしまって、再コンパイルするまで二度と条件判定が行われません。それでは、環境が変わったり、別のマシンにスクリプトを持って行ったりする時に不都合が発生するかもしれません。

だから、make ハンドラの中で、トップレベルのスクリプトオブジェクトを継承したスクリプトオブジェクトを実行時に生成して、そのスクリプトオブジェクトに置き換えるハンドラを持たせます。

ちなみに、トップレベルのスクリプトをクラス、make ハンドラをコンストラクタ、make ハンドラで生成したスクリプトオブジェクトをインスタンスととらえると、クラスベースのオブジェクト指向プログラミングへの道が開けます。

on new_handler()
display alert "new handler"
end new_handler

on old_handler()
display alert "old handler"
end old_handler

on make
script Instance
on say_hello()
display alert "will exchange handler"
script HandlerSwitch
considering numeric strings
if system version of (get system info) is greater than "10.8" then
new_handler
else
old_handler
end if
end considering
end script
set say_hello to run HandlerSwitch
say_hello()
end say_hello
end script
end make

on run
tell (make)
say_hello()
say_hello()
end tell
end run