このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

Erlangのとても困ったところ:階層的パッケージ

えーい、コレのついでだ。もう一つ不満を言っておこう。

[追記]これ、早とちりと感情論が入ってます。「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).を付けておくこと。

これじゃ、パッケージ使う気も失せるよね。