我在API文档中读到*file*
变量的值应为"正在评估的文件的路径,作为字符串".但是,在某些情况下,此功能似乎已被破坏.
当我使用文件执行时lein exec
,事情按预期工作:
$ cat test.clj
(println *file*)
$ lein exec test.clj
/path/to/test.clj
Run Code Online (Sandbox Code Playgroud)
然而,当我运行包含调用的测试时(println *file*)
,NO_SOURCE_PATH
将打印而不是包含该行的文件.
为什么我会看到此行为,如何可靠地访问正在评估的文件的路径和文件名?
Cho*_*ser 13
*file*
被设置为正在编译的文件的路径,因此在编译整个程序之后,查看*file*
(假设不使用eval)的值不再有用.
在您的test.clj
示例中,在println
文件仍在编译时执行.如果将引用*file*
移动到测试或函数中,则只有在值*file*
不再有用后才会在运行时取消引用.
一种选择是编写一个存储*file*
扩展时间值的宏,以便稍后使用.例如,文件example.clj
可能具有:
(defmacro source-file []
*file*)
(defn foo [x]
(println "Foo was defined in" (source-file) "and called with" x))
Run Code Online (Sandbox Code Playgroud)
然后从REPL或任何地方,(foo 42)
将打印:
Foo was defined in /home/chouser/example.clj and called with 42
Run Code Online (Sandbox Code Playgroud)
请注意,source-file
定义哪个文件无关紧要,只有在展开的位置,即foo
定义的文件.这是有效的,因为它是在运行时foo
编译的source-file
,并且其返回值source-file
只是一个字符串,然后包含在编译版本中foo
.然后,每次foo
执行时都可以使用该字符串.
如果这种行为令人惊讶,那么为了*file*
在运行时在每个函数中都有一个有用的值,可能需要考虑一下会发生什么.它的值必须为每个函数调用和返回而改变,这是很少使用的特性的大量运行时开销.
归档时间: |
|
查看次数: |
220 次 |
最近记录: |