[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ライブラリで定義されている関数, 変数をカプセル化する仕組みが モジュール (module) である. はじめにモジュールを用いたプログラムの例をあげよう.
module stack; static Sp $ Sp = 0$ static Ssize$ Ssize = 100$ static Stack $ Stack = newvect(Ssize)$ localf push $ localf pop $ def push(A) { if (Sp >= Ssize) {print("Warning: Stack overflow\nDiscard the top"); pop();} Stack[Sp] = A; Sp++; } def pop() { local A; if (Sp <= 0) {print("Stack underflow"); return 0;} Sp--; A = Stack[Sp]; return A; } endmodule; def demo() { stack.push(1); stack.push(2); print(stack.pop()); print(stack.pop()); } |
モジュールは module
モジュール名 〜 endmodule
で囲む.
モジュールは入れ子にはできない.
モジュールの中だけで使う大域変数は static
で宣言する.
この変数はモジュールの外からは参照もできないし変更もできない.
モジュールの外の大域変数は extern
で宣言する.
モジュール内部で定義する関数は localf
を用いて宣言しないといけない.
上の例では push
と pop
を宣言している.
この宣言は必須である.
モジュール moduleName
で定義された関数 functionName
を
モジュールの外から呼ぶには
moduleName.functionName(引数1, 引数2, ... )
なる形式でよぶ.
モジュールの中からは, 関数名のみでよい.
次の例では, モジュールの外からモジュール stack
で定義された関数 push
,
pop
を呼んでいる.
stack.push(2); print( stack.pop() ); 2 |
モジュールで用いる関数名は局所的である. つまりモジュールの外や別のモジュールで定義されている関数名と同じ名前が 利用できる.
モジュール機能は大規模ライブラリの開発を想定している.
ライブラリを必要に応じて分割ロードするには, 関数 module_definedp
を用いるのが
便利である.
デマンドロードはたとえば次のように行なえば良い.
if (!module_definep("stack")) load("stack.rr") $ |
asir では局所変数の宣言は不要であった.
しかしモジュール stack の例を見れば分かるように, local A;
なる形式で
局所変数を宣言できる.
キーワード local
を用いると, 宣言機能が有効となる.
宣言機能を有効にすると, 宣言されてない変数はロードの段階で
エラーを起こす.
変数名のタイプミスによる予期しないトラブルを防ぐには,
宣言機能を有効にしてプログラムするのがよい.
モジュール内の関数をそのモジュールが定義される前に 呼び出すような関数を書くときには, その関数の前でモジュールを次のように プロトタイプ宣言しておく必要がある.
/* Prototype declaration of the module stack */ module stack; localf push $ localf pop $ endmodule; def demo() { print("----------------"); stack.push(1); print(stack.pop()); print("---------------"); } module stack; /* The body of the module stack */ endmodule; |
module_list
, 6.12.2 module_definedp
, 6.12.3 remove_module
.