2011-06-22 35 views
5

我试图使用Clojure doc函数获取文档,但无法从REPL中识别它(我正在使用Emacs和SLIME)。下面的步骤描述(每行后错误信息如下立即)这是怎么回事:为什么REPL将clojure.core/doc视为var?

gaidica.core> (doc first) 
; Evaluation aborted. 

Unable to resolve symbol: doc in this context 
    [Thrown class java.lang.Exception] 

gaidica.core> (clojure.core/doc first) 
; Evaluation aborted. 

No such var: clojure.core/doc 
    [Thrown class java.lang.Exception] 

user> (clojure.core/doc first) 
; Evaluation aborted. 

No such var: clojure.core/doc 
    [Thrown class java.lang.Exception] 

user> (doc first) 
------------------------- 
clojure.core/first 
([coll]) 
    Returns the first item in the collection. Calls seq on its 
    argument. If coll is nil, returns nil. 
nil 
user> 

如何我指的是doc功能,并把它视为一个功能,而不是一个变量?


附录,11年6月22日,9小时后问题发表

@kotarak做出了最相关的注释:“请注意,这clojure.core/DOC是1.2和更早clojure.repl/doc是1.3及更高版本。“果然,下面的工作:

user> (clojure.repl/doc first) 
------------------------- 
clojure.core/first 
([coll]) 
    Returns the first item in the collection. Calls seq on its 
    argument. If coll is nil, returns nil. 
nil 
user> 

我能确认的Clojure 1.3活跃:

user> *clojure-version* 
{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"} 
user> 

然而,这也令人困惑 - 我Leiningen project.clj已指定的Clojure 1.2!

以我自己的经验,我曾经注意到,即使在更改相关目录的内容后,基于SLIME的REPL“挂在”Java类路径值上。解决方案然后是退出Emacs和lein swank,然后重新输入并重试。我想同样的,得到了​​以下结果:

user> *clojure-version* 
{:major 1, :minor 2, :incremental 0, :qualifier ""} 
user> 

的唯一结论,我可以做的是,我以前曾REPL使用Clojure的1.3去过。我在之前编写的项目有使用了Clojure 1.3快照,所以我猜测REPL已经以某种方式“挂在”Clojure 1.3上。

问题解决了,学到了什么教训等等。对于奖励积分,任何人都可以解释发生什么事情的原因(使用Clojure 1.2与1.3)?

感谢所有人的贡献。

+0

我注意到你还没有接受任何回答您的任何问题。如果你认为他们足够,你应该肯定接受一些答案。这是stackoverflow网站的工作原理。 – bmillare

+0

@kotarak和@bmillare:请阅读我的问题和两个答案。我认为你会同意,虽然这两个答案都试图有帮助,但都不回答我的问题。这就是为什么我还没有接受。 –

+0

@ gregg-williams对于您的所有其他问题而言,这确实如此,您没有提供任何反馈意见,无论提出的解决方案是否有帮助。 – kotarak

回答

12

几个更正。首先,doc是一个宏而不是一个函数。函数和宏也可以存储在var中。其次,在clojure 1.3中,这可能是您正在使用的版本,doc存储在var clojure.repl/doc中,而不是clojure.core/doc(如1.2中所示)。在命名空间用户中,doc是“used”,又名是隐含的“(使用[clojure.repl:只有[doc])”)。当你得到一个新的命名空间,或者甚至用ns创建一个命名空间时,clojure.repl/doc不会自动添加,与'user'不同。

更明确的有关问题:

为什么REPL治疗clojure.core/DOC作为一个变种?

clojure中的函数,宏和值都存储在变量中,或者绑定到一个符号,比如在一个函数或函数中。 clojure.core/doc是持有执行doc的宏的变量。

如何引用doc函数并将它识别为函数而不是变量?

和所有的lisps一样,要做一个调用,无论是一个函数还是一个宏,你都必须把函数/宏放在列表的第一个位置。

(<fn/macro> *args) 

所以叫上自己的宏的文档,你会怎么做:

(doc doc) 
+3

请注意,'clojure.core/doc'是1.2及更早版本。 'clojure.repl/doc'是1.3及更高版本。 – kotarak

1

的文档的文档显示了它的一个宏,以便与macroexpand显示了 期待一个变种的名称扩展它包含一项功能。所以对你的问题的简短回答是“名字空间中的函数包含在变量中”。

在这样macroexpand-1的情况下可以是一个良好的开端:

(macroexpand-1 '(doc doc)) 
(clojure.core/print-doc (var doc)) 
sso-config.core> (doc doc) 
------------------------- 
clojure.core/doc 
([name]) 
Macro 
    Prints documentation for a var or special form given its name