Go to the first, previous, next, last section, table of contents.


モジュール

ライブラリで定義されている関数, 変数をカプセル化する仕組みが モジュール (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 を用いて宣言しないといけない. 上の例では pushpop を宣言している. この宣言は必須である.

モジュール moduleName で定義された関数 functionName を モジュールの外から呼ぶには moduleName.functionName(引数1, 引数2, ... ) なる形式でよぶ. モジュールの中からは, 関数名のみでよい. 次の例では, モジュールの外からモジュール stack で定義された関数 push, pop を呼んでいる.

 stack.push(2);
 print( stack.pop() );
 2

モジュールで用いる関数名は局所的である. つまりモジュールの外や別のモジュールで定義されている関数名と同じ名前が 利用できる.

モジュール機能は大規模ライブラリの開発を想定している. ライブラリを必要に応じて分割ロードするには, 関数 module_definedp を用いるのが 便利である. デマンドロードはたとえば次のように行なえば良い.

if (!module_definedp("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;

モジュールの中からトップレベルで定義されている関数を呼ぶには, 下の例のように :: を用いる.

def afo() {
  S = "afo, afo";
  return S;
}
module abc;
localf foo,afo $

def foo() {
  G = ::afo();
  return G;
}
def afo() {
  return "afo, afo in abc";
}
endmodule;
end$

[1200] abc.foo();
afo, afo
[1201] abc.afo();
afo, afo in abc
参照
section module_list, section module_definedp, section remove_module.


Go to the first, previous, next, last section, table of contents.