2010/08/11

ユニット(拡張ライブラリスクリプト)の読み込み方法

NILScriptでは、主要な機能以外の多くの機能は「ユニットスクリプト」というライブラリになっており、実行時に必要になった時点で動的に読み込んで使うようになっています。
ユニットというのはDelphiに倣った呼称で、「ライブラリ」や「モジュール」にしなかったのは、DLLなどと混同されないようにするためです。
今回は、ユニットで定義されているクラスを利用するためのいくつかの方法について説明します。

最も推奨される方法は「require()」です。この関数は、引数で指定したユニットを読み込んで、Unitクラスのインスタンスオブジェクトを返します。ユニットが提供するクラスなどは、このオブジェクトのメンバとして格納されています。
なお、同じユニットを複数回require()した場合、読み込みや初期化が行われるのは最初の1回だけで、以降は1回目の返り値が使い回されます。
ユニットが提供するクラスを複数回使用する場合は、このオブジェクトを変数に代入しておくとより効率的ですが、1回しか参照しない場合は「require("HTTPD").HTTPD.create(/*...*/);」のように、直接配下のクラスの機能を呼び出しても構いません。
提供されるクラスが1つだけのユニットを使う時や、使いたいクラスが1つだけの場合は、「var Clipboard=require("Clipboard").Clipboard;」のように、使いたいクラス自体を変数に代入してもいいでしょう。
また、分割代入という方法を使えば、「var {Keyboard,Key}=require("Keyboard");」のようにして、複数のクラスをローカル変数に代入することも可能です。
ユニットで定義されている名前とは別の名前の変数に代入したい場合は、「var {Keyboard:KB,Key}=require("Keyboard");」のようにすることも出来ます。この場合、Keyboardクラスは「KB」というローカル変数に代入されます。

一方、最も手軽な方法は、「use()」です。こちらは、引数で指定した名前のユニットで提供されているメンバをグローバル変数として展開します。
use()は手軽な反面、既存のグローバル変数を上書きしてしまうので、注意が必要です。
ユニットが提供するクラスの中には、標準状態でグローバルに定義されているクラスや、他のユニットから展開されたクラスと同じ名前のクラスが存在する可能性があるからです。
use()は、数行程度の簡単なスクリプトでしか使わない方がよいでしょう。特に、自作のユニットスクリプトの中で使うのは絶対に避けてください。

ユニットが提供するクラスを、グローバル変数としてではなくローカル変数として展開する方法として、「eval(Unit())」という書き方も用意されています。
「Unit」を関数として呼び出すと、引数で指定した名前のユニットを読み込んで各メンバをローカル変数に代入するという内容のスクリプト文字列が返されます。これをeval()することで、その場所のローカル変数に展開するのです。
この時、「var」による関数スコープではなく、「let」によるブロックスコープが使用されます。
既存のグローバル変数と重複する名前のクラスが定義されているユニットを手軽に使いたい場合などに利用するといいでしょう。
ただし、何のブロックの内側でもないトップレベルで使用すると、グローバル変数を上書きしてしまうので注意してください。

また、応用的な方法として「with(reqiure()){/*...*/}」という書き方も出来ます。
この場合、withブロックの中ではrequire()が返したUnitオブジェクトのメンバをローカル変数のように利用できます。
比較的手軽で安全なので、覚えておくとよいでしょう。

0 件のコメント:

コメントを投稿