*file*
はコンパイルされるファイルのパスに設定されるため、プログラム全体がコンパイルされた後は、 *file*
(eval を使用しないと仮定して) の値を調べることはもはや役に立ちません。
あなたのtest.clj
例ではprintln
、ファイルがまだコンパイルされている間に実行されます。への参照が*file*
テストまたは関数に移動された場合、 の値が*file*
役に立たなくなった後、実行時にのみ逆参照されます。
1 つのオプションは、*file*
展開されたときの値を格納するマクロを作成して、結果を後で使用できるようにすることです。たとえば、ファイルには次のようなexample.clj
ものがあります。
(defmacro source-file []
*file*)
(defn foo [x]
(println "Foo was defined in" (source-file) "and called with" x))
次に、REPL またはどこからでも、次の(foo 42)
ように出力されます。
Foo was defined in /home/chouser/example.clj and called with 42
どのファイルsource-file
で定義されているかは問題ではなく、展開された場所、つまりが定義されているファイルであることに注意してくださいfoo
。これが機能するのは、foo
がコンパイルされたときにsource-file
実行され、 の戻り値source-file
が単なる文字列である のコンパイル済みバージョンに含まれるためですfoo
。foo
もちろん、文字列は実行するたびに利用できます。
この動作が驚くべきものである場合は*file*
、実行時に がすべての関数内で有用な値を持つために何が起こる必要があるかを検討することが役立つ場合があります。その値は、関数の呼び出しと戻りごとに変更する必要があり、めったに使用されない機能の場合、かなりの実行時オーバーヘッドになります。