※ 「targetengine」は「InDesign」、および「Illusutrator」にのみ対応

 

<targetengineは「名前空間」の指定である>

 

直列的に処理をこなして終了するスクリプトは同時に2つ以上実行されることはないので、結果的に排他的な環境で実行されます。adobeのJavaScript環境(ExtendScript)であれば、スクリプトは「main」という空間で実行され、終了後は暗示的にクリアされます。

それに対して常駐するスクリプトは、その実行環境を維持し続けるための「居場所」が必要になります。その場合、同じ居場所で不特定多数のスクリプトが実行されると、変数名の衝突が起こるなどの不都合が生じます。

 

それを回避するために用意されているのが「名前空間」という仕組みで、同じ名前の変数などが複数存在しないように、変数が存在する空間(実行環境)を切り分ける概念のことです。

その名前空間をExtendScriptで実現するために用意されているのが「targetengine」です。これによって各スクリプトは変数名の衝突が起こらない「固有の名前空間」を作成し、そこに常駐できるようになっています。

 

<どんな時に必要になるか?>

 

前述のとおり常駐するスクリプトがその対象で、例として以下のようなものが挙げられます。

  • パレットウィンドウ(フローティングウィンドウ)
  • BridgeTalkによるアプリケーション間通信
  • アプリケーションのイベント(メニューなど)、もしくはスクリプト自体のイベントを待ち受ける類

 

<targetengineについての検証>

 

常駐型スクリプトを走らせる場合、それぞれのスクリプトは変数名の衝突を避けるために固有の名前空間が必要です。

しかし、巷ではadobeのリファレンスに書いてあるまま、「#targetengine "session"」と宣言しているものが少なくありません。もし、このようなスクリプトを同時に実行していたとすれば、それはかなり危険な行為です。

 

その懸念を明らかにするため、同じ名前空間でグローバルに定義された変数と関数が、どのように共有されるかを検証してみました。

 

まず、次のスクリプトを実行します。 

//Window A
#targetengine "session"
//グローバル変数
var mainWindow;
//--------------------------------------

//  window構築関数

//--------------------------------------
function makeWindow(wName, xa, ya, xb, yb) {
    var newWindow= new Window ('palette', wName, [xa, ya, xb, yb], {closeButton: true});
    var btnObj = newWindow.add( 'button', [10, 40, 10+130, 40+20], 'test', { button: true } ); //ボタン作成
    btnObj.onClick = function() { alert( dummyStr ); }
    return newWindow;
}
//--------------------------------------

//  メイン部

//--------------------------------------
mainWindowA= makeWindow('Window A', 8, 30, 158, 130); //window構築
mainWindowA.show();

この時点では「window A」が問題なく表示されます。window AにあるボタンにはonClickイベントが設定されており、変数dummyStrの値が表示されることになっていますが、この状態ではdummyStrがundefinedのために何も起こりません。

 

では次に、このwindow Aを立ち上げたままで以下のスクリプトを実行します。 

//Window B
#targetengine "session"
//こちらにはwindowを構築する関数はない。
//その代わりこちらだけに以下のグローバル変数を定義
var dummyStr="from window B"
//--------------------------------------

//  メイン部

//--------------------------------------
mainWindowB= makeWindow('Window B', 168, 30, 318, 130); //window構築
mainWindowB.show();

すると、こちらにはwindowを構築する関数が存在しないはずのに「window B」が構築されます。

そして、先ほどは何も起こらなかった「Window A」のボタンを押すと、ここでは後に起動した「Window B」で宣言した「dummyStr」の値("from window B")が表示されます。

 

このことから、起動の後先にかかわらず、同じ名前空間ではグローバルな関数や変数が共有されていることが証明されました。考えもなしに「#targetengine "session"」と宣言することが、いかに危険な行為なのかがわかります。

 

サンプルやリファレンスに詳細な説明がないので、「session」という名前があたかもデフォルトのセレクタか何かのように思ってしまいますが、「session」は単なる例文にすぎません。

常駐するスクリプトは「#targetengine "hogehoge"」というように、それぞれ固有の名前空間で実行されなければなりません。

 

 

Joomla templates by a4joomla