Erlang World


top > module and function > package

Package

パッケージ

初期のErlangのモジュールには階層構造がありませんでしたが、 モジュールを機能ごとに分類するためにパッケージという概念が導入されました。
Erlangにおけるパッケージとは、「モジュールの階層構造」のことを表しています。Javaのパッケージは アクセス手段等の複雑な役割を持っていますが、Erlangのパッケージは物理的な階層構造を中心とする概念のため 特に難しいものではありません。

パッケージはBIFのpackageが 管理しているものです。この節ではおもに利用方法だけを利用しますので、より詳細に調べたい方は マニュアルを参照下さい。

パッケージの利用

パッケージを利用する際に、今までと違った点が2つあります。
それは

という点のみです。特に新しい関数などは利用しません。

以下では簡単なサンプルを扱います。
モジュールの構成としては以下のようになっています。

package_test/main.erl
package_test/pack1/add_mod.erl
package_test/pack2/mul_mod.erl

-module(main).
-export([test/2,out/0]).

test(X,Y) ->
    Add = pack1.add_mod:add(X,Y),
    io:format("add ~p~n",[Add]),
    Mul = pack2.mul_mod:mul(X,Y),
    io:format("mul ~p~n",[Mul]).
	
out() ->
    io:format("in main~n",[]).
-module(pack1.add_mod).
-export([add/2,use_upper_modfunc/0]).

add(X,Y) ->
    X + Y.
	
use_upper_modfunc() ->
    .main:out().
-module(pack2.mul_mod).
-export([mul/2]).

mul(X,Y) ->
    X * Y.

注目するべき点は、モジュールの宣言とモジュールの呼び出し部分でした。
階層構造が符号 . で繋がれているのがわかります。

特に難しい点はないと思うのですが、一つだけ注意したほうがいい点があります。 それは、「パッケージ名(ディレクトリ名)もアトムである」という点です。
したがって、パッケージ名はアトムと同様に小文字英語から始めることが推奨されます。 スペースの利用や、日本語の利用はエラーの元になるので避けることが望ましいです。

実行結果は以下の通りになります。
普通の関数と同じように動いているのがわかります。

> main:test(3,5).
add 8
mul 15
ok

パッケージ詳細

ある程度パッケージという概念について理解できたと思うので、もう少し詳細に見ていきます。
まずは実験からスタートしてみます。add_modを直接呼び出してみます。

> pwd().
/Users/yuichi/erlang/package_test/pack1
ok
> add_mod:add(3,4).

=ERROR REPORT==== 7-Jun-2008::13:15:41 ===
Loading of /Users/yuichi/erlang/package_test/pack1/add_mod.beam failed: badfile
** exception error: undefined function add_mod:add/2
=ERROR REPORT==== 7-Jun-2008::13:15:42 ===
beam/beam_load.c(1035): Error loading module add_mod:
  module name in object code is pack1.add_mod
  
> pack1.add_mod:add(3,4).
7

add_modというモジュール名で呼び出すとエラーが出ています。pack1.add_modというモジュール名で呼び出すと大丈夫なようです。
モジュール名はモジュール名宣言されたものと同じ名前で利用しないと駄目なようです。

次に上の階層にあるモジュールを利用してみます。

> pwd().
/Users/yuichi/erlang/package_test/pack1
ok
13> pack1.add_mod:use_upper_modfunc().
in main
ok

use_upper_modfunc/0の中を見てみると、mainの関数の呼び出しが
.main:out().
のようになっています。一番最初に . がついています。これはパッケージの階層の一番上を意味しています。
パッケージは一番上の階層を起点として、絶対表記を行ないます。 今回のプログラムのルートパッケージは package_test です。

また、関数の呼び出しの際に、モジュールが属するパッケージ名を省略した場合は 自分と同じ階層にあるモジュールだという扱いになります。

BIFはルートパッケージにあるという扱いになっていますので、利用する際は
.lists:reverse(List).
といった呼び出し方を行ないます。

モジュールのインポート

モジュールのインポートも可能です。インポートの際に、 ルートパッケージからの階層を記したモジュールを指定するのみです。

-import(fee.fie.foe.m2).

fee fie foe がパッケージ名で m2 がモジュール名となっています。
インポートを行なうことで、本来なら
fee.fie.foe.m2:h(X)
と呼び出さないといけないものを、
m2:h(X)
と呼び出すことが可能となります。


Yuichi ITO. All rights reserved.
mail to : ad
inserted by FC2 system