ライブラリ機能の続きになります。
まだ続くんかいってところですが、色々と変わっているんですね。久しぶりに触ってみると。
AppleScript/Objective-C(以降は ASOC と略します)は、以前(いつ頃からだっけ?)から利用できたのですが、それが AppleScript のライブラリ機能と組み合わさるとどうなるのか?
古くは ScriptingBridge。そして、Xcode での ASOC アプリケーションのサポート。最近では AppleScript Editor で ASOC アプレットサポート...。こうやって段階を踏んできたのですが、やっと、通常のスクリプトで ASOC が利用できる環境が整ってきました。
と、Objective-C 利用の話に進もうと思ったのですが、前回の補足を少し。
まず、前提として OS X Mavericks の AppleScript 2.3 で追加された機能...。
- スクリプトライブラリ
- use 構文
- AppleScript Editor でのコード署名対応
- 通知センターのサポート
等々...。まぁ、他にもありますが。以上のような機能は全て OS X Maverics 以降でしか利用できません。特にスクリプトライブラリと use 構文には後方互換がありません。これらを積極的に利用するなら、OS X Mavericks 以前の環境は切り捨て...になります。
ただ、スクリプト内で実行環境を調べることはできるので Mavericks 以前と以後でのスクリプトの挙動を制御することは可能です。
あと、use 構文....この構文については別で取り上げようと思っていたので詳しい説明は省いていました。ただ、一点だけ。
use FinderUtilities : script "Finder Utilities"
この構文ですが、
property FinderUtilities : script "Finder Utilities"
と意味的には同じです。変数へのアサインです。これ以上でも以下でもない。唯一の違いは use を利用すると『必ず、最新のライブラリを読み込む』ということです。
いろいろ試しているのですが use 構文は単純に tell 構文を置き換えるもの...でもなく、癖があって使いにくい。長くなるのでまた今度、ということで。
あと、ライブラリを色々なところから利用するときのこと。
handlerA()
handlerB()
displayCounter() of script "Counter"
on handlerA()
countup() of script "Counter"
end handlerA
on handlerB()
countup() of script "Counter"
end handlerB
このようなスクリプトなんですが、このときライブラリは何回呼び出されるのか?ライブラリはスクリプト内に取り込まれた後、それが使い回されます。シングルトン?とでもいえばいいのか...(複製はできるんだけど)。そして、ライフサイクルはスクリプトが始まってから終わるまで、です。
最後に。Script factory さんからの質問。
@badcharan 配布することを前提とした AppleScript アプリケーションをつくりたいとします。その為に、ライブラリはすべてコンパイル時に property に読み込むとします。
— Tetsuro Kurita (@t_kurita) November 8, 2013
@badcharan ライブラリ A をトップレベルから読み込み、ライブラリ A をの中からライブラリ B を読み込むとします。コンパイル時にライブラリの読み込みを完了したいのだから、ライブラリ A の property にライブラリ B に読み込みます。
— Tetsuro Kurita (@t_kurita) November 8, 2013
@badcharan さて、ライブラリ A を読み込んだ時、ライブラリ B は最新のものに更新するにはどうすれば良いのでしょうか。どうも、できるように思えない。自分で、検証しろという気もしますが、ネタとして。
— Tetsuro Kurita (@t_kurita) November 8, 2013
と、いうことなんですが...。
property にスクリプトオブジェクトを読み込むと、コンパイル時の状態が保たれます。例えば、まだスクリプトはデバッグ中だよ、というフラグを作ります。
property DEBUG : true
これを他のスクリプトの property にスクリプトオブジェクトとして読み込みます。当然、読み込んだ方のスクリプトではこの状態を保ったままにします。
property DEBUG : false
デバッグが終わったのでこのように変更します。しかし、読み込んでいる方のスクリプトでは以前の状態(デバッグ中!)のままです。変更は反映されません。どうしてかというと、 property がそういう性質のものだからです(手抜きだなぁ)。property はコンパイル時に評価され、コンパイル時のスクリプトオブジェクトをそのまま保持しているんですね。変更するには再度、コンパイルする必要があります。
つまり、おおもとの(状況によっては全ての関連する)ファイルを開いて編集して再コンパイルして再保存...面倒ですね。自分で使っているぶんにはまだしも、配布しているスクリプト、ましてや実行専用のものだと利用者に労力を割いてもらわなければなりません。こういう事態は避けたいものです。
では、実行時に最新の状態を property に読み込むようにするにはどうすればいいのか?ということなんですが、個人的には一番簡単な方法を使っています。つまり、実行時に読み込む。
property theObject : missing value
set theObject of me to load script file "/script/file/path"
もしくは、
set theObject of me to my makeObject(load script file "/script/file/path")
on makeObject(theObject)
script
property scriptObject : theObject
end script
end makeObject
このような感じ。
おそらく、Script factory さんの求めている答えと激しく異なっていると思いますが...。
理由としては、『確実』だからでしょうか。問題としては依存している全てのファイルが必要、管理が面倒、融通が利かない...等々、問題点の方が多いのですが。
こういう問題って、みんなどうしているんでしょう?
激しく謎です。
以上。補足でした。って、結構な長さになってしまった...。Objective-C 利用の話に進もうと思っていたのに。
今更ですが、この時自分が聞きたかったのは、
返信削除http://www.script-factory.net/history/2016/03/30_1156.xhtml
ということです。