2010-03-21T09:48:23+09:00

ちゃらんぽらんさんの「ModuleLoader.osax の真価」へのコメント

すごいタイトルの記事を書いていただいた。本当にありがとうございます。ModueLoader の啓蒙が少しでもすすめばいいと思うのだけど。

ところで、一つ前の「load script を置き換える」で一つコメントし忘れたがことがある。

正直なところ「このスクリプトには OSAX が必要です。こちらからダウンロードしてください」とユーザー(もちろん、ユーザーには未来の自分も含まれます)の手を煩わせるのがいやなのですが...。

についてです。未来のユーザーに対してはどうしようもないのだけど、現在の自分以外のユーザーの為には、

とすれば、だいたいは技術的には問題解決となる。あとは、他の人が作った OSAX を自分のスクリプトに含めて配布しちゃっていいかという問題があるのだけど。実際のところ、作者にコンタクトして了解を取るしか無い。僕が作った OSAX に関してなら遠慮なくアプリケーションバンドルの中に含めて配布しちゃってもいい。一言伝えてくれるといい気になって喜ぶのだけど。

しかし、ModuleLoader の場合は事情が違う。ModuleLoader を使ってスクリプトを開発したからと言って、そのスクリプトを配布する際に「このスクリプトには OSAX が必要です。こちらからダウンロードしてください」なんていう必要が無い。モジュールをコンパイル時に全部 property にロードするようにすれば、実行時に ModuleLoader は必要ない。これは誤解しないでいただきたい重要なことだ。 ModuleLoader を使い始めるハードルは十分に低いと信じている。

さて、「ModuleLoader.osax の真価」へのコメントを始めよう。

AppleScript は基本的にイントロスペクションが弱い。スクリプトの内部からスクリプトについて調べることができません。例えば、グローバル変数の一覧を取得したり、スクリプトオブジェクト、ハンドラについて調べるこもできません。

蛇足になるけど、こういうことをする API はあります。ModuleLoader の内部では使っています。だからこういうことをできるような OSAX は作れますよ。そういう OSAX を作ろうとすこし思ったけど、あんまり役に立たないと思ってやめました。

複数のスクリプトオブジェクトが同じオブジェクトを参照する...ということなら ModuleLoader.osax を使わずに行うことは可能です。方法は 2 通りあります。

  1. オブジェクトの参照をオブジェクトに渡す(オブジェクトコンポジション)
  2. オブジェクトをシングルトンとして設計する

オブジェクトコンポジションは問題なく行えますし、シングルトンは...厳密にはシングルトンにはできませんが、似たようなことはできます。

この辺は、良く理解できない/同意できないですね。ModuleLoader でしていることは、同じスクリプトファイルを重複して読み込まないようにキャッシュするということであって、デザインパターンとは関係ないです。

次に、

ModuleLoader.osax の boot 命令を使って同一のスクリプトファイルから読み込むと、依存しているスクリプト間では同一のスクリプトオブジェクトを参照するのでした。では、そうしたくないときは?

ちゃらんぽらんさんは、無理して ModuleLoader の機能を使おうとしているけど、そうではなくて実行時に copy コマンドで複製するのがいいんじゃないでしょうか。

property object_A : module "Value"
property object_B : missing value
property loader : boot (module loader) for me

on run
copy object_A to object_B
end run

コンパイル時に複製を作る為には、もうちょっと頑張らなければいけないけど、これで十分な気がします。

さて、僕が ModuleLoader で、いつか打破したい状況は、ちゃらんぽらんさんが次の一言であらわされています。

多くの人が同じようなハンドラを毎回、毎回作っているのが現状です。どうしてなのでしょうか?

でも、こういうこと以前に、同じ人がスクリプトごとに同じハンドラを書いていたりしていませんか?XModules として AppleScript のモジュールライブラリを公開しているけど、実はそんなに使ってもらえることを期待していない。だって、そういう文化さらには文化以前に技術が AppleScript には存在していないのだから。だから、まずは ModuleLoader を普及させたい。だから、ちょっとでも試してみてね。

ちなみに、

このような形で AppleScript をハックしないことには property にスクリプトオブジェクトを読み込めないのでしょう。

「ハック」というと、undocumented な API の使用や API へのフック/パッチを行っていると誤解されている気がします。そういう悪いことはいっさいしていないです。全部、AppleScript と OSA API の素直な仕様の範囲でやっています。将来的に ModuleLoader が動かない/動かすように変更できないことがあれば、Apple が AppleScript にバグを混入したと言ってもいいです。だから安心して使ってください。

次に、

コンパイル時に property にスクリプトオブジェクトを代入するのを好まない人もいると思います

とのことですが、ModuleLoader を使っていなくても、property で load script するのが普通だと思っていたけど、違うのかしら?現実問題として、そういう風に収束すると思うだけど。そして、マニュアルには書いていなかったけど、次のように実行時にローカル変数にモジュールを読み込むことはできます。

tell (module loader)
set object_A to load module "Value"
end tell

ModuleLoader には、多くの人の要求に応えられるだけの柔軟性があると思っています。でも、マニュアルには自分が一番いいと思う、記述が一番少なくて済む方法だけを説明しています。現実的な問題として、マニュアルに書いてあること以外の何が必要なのか、教えていただけると幸いです。

ModuleLoader.osax はマニア向けの OSAX だな、という感じがします。

ライブラリ/モジュールというプログラミングの要素は、マニア向けではないはずです。一定以上の規模/数のスクリプトを書くようになったら、避けて通れない。ちゃんと取り組まないと小学生のようなスクリプトから発展しません。そうなったら ModuleLoader を試してみてください。そして、ご意見/ご感想をください。マニア向けにならないように、取っ付きやすいように改良します。