読者です 読者をやめる 読者になる 読者になる

日曜プログラミング

休日趣味でやってるプログラミング関連記事をダラダラと

Clojure の名前空間とファイル名

Clojure では名前空間を切る時、通常は名前空間名と.cljを除いたファイル名を同じにするよう構成する事になっている。 また、名前空間をドットで区切るのはパス区切りと対応付けられる。

名前空間foo.bar だったら foo\bar.clj となる。

一方、lisp でのシンボル名は通常ハイフン(-)区切りが慣習になっている。 で、名前空間でもこの慣習に従ってハイフン付きで同じファイル名で保存後 require などと すると Java の命名可能文字列仕様の制限にぶち当たる。

例えば

(ns foo.bar-baz)

名前空間を定義し、ファイル名を foo\bar-baz.clj として

(require 'foo.bar-baz)

としても

CompilerException java.io.FileNotFoundException: Could not locate foo/bar_baz__init.class or foo/bar_baz.clj on classpath: , compiling:~

と例外が出る。この例外はメッセージにある通り、 ファイル名を foo\bar-baz.clj でなく foo\bar_baz.clj とすれば解決する。

Java 自体の命名可能文字列の話は こちら が分かりやすい。

名前空間下にある関数名の場合はコンパイラで変換してくれるのか気にしなくてもいいだけに 個人的には若干気持ち悪い。解決策あるからいいっちゃいいんだけど。

これ あんまり Java 知らない Clojure 使いは一度は引っかかるんじゃないのかなあ。 そういや Clojure に最初から入っているライブラリの名前空間名にもハイフン付きって見た事ないな。