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 に最初から入っているライブラリの名前空間名にもハイフン付きって見た事ないな。