Clojureでのrequireと名前空間の関係の簡単な整理。多分Javaと同じだと思うけれど、ディレクトリと名前空間を違いをよく理解していなかったので備忘録として。
まずはカレントディレクトリに以下のソースを置く。
(ns com.lewuathe.hello)
(defn hello
[name]
(str "Hello," name))
LeiningenのREPLから参照する。
% lein repl
nREPL server started on port 52380 on host 127.0.0.1 - nrepl://127.0.0.1:52380
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0-b132
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (require 'com.lewuathe.hello)
FileNotFoundException Could not locate com/lewuathe/hello__init.class or com/lewuathe/hello.clj on classpath: clojure.lang.RT.load (RT.java:443)
見つからないらしい。ファイル名で探す。
user=> (require 'hello)
nil
user=> (com.lewuathe.hello/hello "Kai")
"Hello,Kai"
requireはあくまでもパス名で探すらしい。
名前空間と同じディレクトリ名を掘ってみる。
% mkdir com/lewuathe/hello
% mv hello.clj com/lewuathe/hello
% lein repl
user=> (require 'com.lewuathe.hello.hello)
nil
user=> (com.lewuathe.hello/hello 'Kai')
"Hello,Kai'"
見つかった。requireでソースを探しにいくときは。
(require '<ソースファイルのディレクトリまでのパス>.<ファイル名>)
となるみたい。