在查看defmacro
定义后的clojure.core文件时,您会看到以下代码:
(. (var defmacro) (setMacro))
这意味着什么?
答案 0 :(得分:6)
.
的意思正如Joost和Jeremy的答案所解释的那样。如果您想知道这个特定方法调用所完成的细节:
这基本上将名为:macro
的键值true
插入到名称为clojure.core/defmacro
的Var的元数据映射中。这样做的结果是,从这一点开始,如果编译器在解析为var defmacro
的上下文中遇到符号#'clojure.core/defmacro
(#'foo
是(var foo)
的简写) - 通常在任何地方,尽管你可以,例如使用let
绑定的局部变量来影响此Var - 它将知道在宏名称的情况下它应该适当地对待它。
(也就是说,(1)如果符号#'clojure.core/defmacro
出现在操作员位置,即紧接在开头的右边,则使用绑定到defmacro
的函数扩展宏调用,或者抛出异常来抱怨在非操作员位置提到的宏名称。)
顺便提一下,Clojure编译器通常会在Vars上使用元数据映射,例如:决定各种对象的类型(参见:tag
元数据)或是否内联函数调用(IIRC,:inline
和:inline-arities
)。
答案 1 :(得分:2)
我会分解整行,因为我不知道你已经知道的是什么。
符号必须解析为var,并返回Var对象本身(不是其值)。
如果我们将其输入REPL,我们得到:
user=> (var defmarco)
#'clojure.core/defmacro
现在,.
特殊表单允许您call methods on instances of Java objects。在这种情况下,正在调用返回的Var
对象上的setMacro
method。
我对代码的熟悉程度不足以真正理解setMacro
正在做什么,但我认为它改变了var的状态,说它是一个宏,而不是一个函数或其他东西。
答案 2 :(得分:1)
(。foo(bar))是(.bar foo)的低级别等价物,所以这会在没有参数的defmacro var上调用方法setMacro。
我怀疑此调用将defmacro函数/ var标记为宏。一般来说,clojure.core中的很多东西使用低级技巧来引导语言,所以虽然有趣的是看到东西是如何构建的,但它并不是真正的惯用代码的好来源。