2010-04-01T14:56:03+09:00

AppleScript のスクリプトオブジェクトで is-a 関係を調べられるようにする。

is-a 関係とは、あるオブジェクト/クラス B が別のオブジェクト/クラス A のサブクラスであることをいう。こういうことを AppleScript で調べられるようにできるかしら、ということを考えてみた。

で、つくったコードが次のもの。ルートオブジェクトに is-a 関係を調べる為のハンドラ、is_a、is_a_name を実装するとする。このオブジェクトを継承したオブジェクトから、is_a もしくは is_a_name を呼ぶことで継承関係を調べられる仕組み。

script BaseClassA
property _class_name : "a"

on is_a_name(a_classname)
try
if my _class_name is a_classname then
return true
else
return parent's is_a_name(a_classname)
end if
on error
return false
end try
end is_a_name

on is_a(object)
if me is object then
return true
else
if me is AppleScript then
return false
else
return parent's is_a(object)
end if
end if
end is_a
end script

script ClassB
property parent : BaseClassA
property _class_name : "b"
end script

log ClassB's is_a_name("c") -- false
log ClassB's is_a_name("b") -- true
log ClassB's is_a_name("a") -- true
log ClassB's is_a(BaseClassA) -- true
log ClassB's is_a(ClassB) -- true

さて、ここまで興味本意でやってみて、オブジェクト/クラスを継承していることを調べるのは意味ないな、と気付いた。実際には、あるハンドラ/メソッドに答えてくれるかどうかが問題であるのからね。Cocoa でいう respondsToSelector みたいのが必要だ。スクリプトオブジェクトがあるハンドラを実装しているかどうかは、その ハンドラを get してみて、エラーが起きるかどうか調べればいい。

script ObjectA
on handler_a()
end handler_a
end script

ObjectA's handler_a's class is handler

try
ObjecgtA's handler_b's class is handler
on error
log "No handler_b"
end try

とりあえずは、これでほとんど用が足りるけど、文字列でハンドラを指定したいよね。そんなとき、拙作の AppleScript モジュールXHandler の responded_by を使うことができるよ。XHandler は、文字列でハンドラを指定して実行したりすることができる AppleScript モジュール。そして、script object が文字列で指定したハンドラに応答できるかどうか調べることもできる。

property XHandler : module

boot (module loader) for me

script ObjectA
on handler_a()
end handler_a
end script

log XHandler's make_with("handler_a", 0)'s responded_by(ObjectA)
-- result : true
log XHandler's make_with("handler_b", 0)'s responded_by(ObjectA)
-- result : false

このスクリプトを試すときは、XHandler だけでなく、ModuleLoader もダウンロード/インストールしてね。