えーい、コレのついでだ。もう一つ不満を言っておこう。
[追記]これ、早とちりと感情論が入ってます。「Erlang、ほんとに困るのか?」も見てください。それとこのエントリーのコメント欄も。[/追記]
階層的パッケージはあるのだ
あと、モジュール名って階層構造に出来たっけ?
できます。http://www.erlang.org/doc/man/packages.htmlを参照のこと。
コードパス(他の言語/環境におけるライブラリパスとかクラスパスに相当)に含まれるディレクトリのサブディレクトリfoo/bar/ にmymod.beamがあれば、それはフルネームが foo.bar.mymod というモジュールになります。
ディフォルトパッケージやカレントパッケージという概念はなくて、修飾なしのモジュール名はパッケージ&モジュール名前空間のルート直下に配置されます。つまり、パッケージ名モジュール名mymodは.mymod(先頭ピリオドに注意)のことだと解釈するわけ。
が、しかし…
階層的パッケージは後から追加された機能のようです。しかしそれにしても、使っている例が全然見あたらない。なんでだ? 関数呼び出しに若干のオーバーヘッドがあるかもしれませんが、深刻とは思えません。
実際に使ってみると… 案の定…。まー、次の例を見てください。
このモジュールはコンパイルできますが、
-module(foo.hello).
-export([greet/0]).greet() ->
io:fwrite("Hello, world.\n").
foo.hello:greet().
と呼び出すと奇妙なエラーを引き起こします。
> foo.hello:greet().=ERROR REPORT==== 17-May-2007::01:47:08 ===
Error in process <0.30.0> with exit value: {undef,[{'foo.io',fwrite,
["Hello, world.\n"]},{erl_eval,do_apply,5},{shell,exprs,6},
{shell,eval_loop,3}]}** exited: {undef,[{'foo.io',fwrite,["Hello, world.\n"]},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]} **
>
foo.io:fwriteが未定義だと言っているようです。どうも、パッケージfooに含まれるモジュール内でio:fwriteのように書くと、パッケージ名が勝手に付加されてfoo.io:fwriteと解釈されるようです。これ酷すぎ! とりあえずの回避策は、-import(io).
を付けておくこと。
これじゃ、パッケージ使う気も失せるよね。