如何在Clojure宏扩展时确定

时间:2012-01-13 14:27:52

标签: clojure

我相信我理解在宏扩展期间,宏无法访问函数可以访问的内容,因为扩展在编译时发生。

但是,我无法理解如何在宏扩展时执行检查。

例如:

(defn gen-class [cl-nam]
    (fn [cmd & args]
        (condp = cmd
            :name (name cl-nam))))

(defmacro defnclass [cl-nam]
    `(def ~cl-nam (gen-class '~cl-nam)))

我想查看cl-nam不是序列。我想用count来查找它的长度是> 1.

我知道我可以在下面的宏中取消引用println,这样我就可以获得扩展时消息。

(defmacro defnclass_info [cl-nam]
    `(do
        ~(println cl-nam)
        (def ~cl-nam (gen-class '~cl-nam))))

但是,我不知道如何检查cl-nam的传递内容。

我正在阅读几本书中的很多Clojure宏描述,但我很难过。 感谢。

1 个答案:

答案 0 :(得分:5)

宏实际上只是一个功能。

(defmacro defnclass-info
  [cl-name]
  (when (seq? cl-name)
    (throw (Exception. "cl-name must not be a sequence")))
  `(def ~cl-name (gen-class '~cl-name)))

编辑:还可以切换行为,并为整个列表再次递归调用宏。你做什么,取决于你的要求。

(defmacro defnclass-info
  [cl-name]
  (if (seq? cl-name)
    `(do ~@(for [cn cl-name] `(defnclass-info ~cn)))
    `(def ~cl-name (gen-class '~cl-name))))

宏扩展正是"功能"回报。因此,您可以完全灵活地处理宏参数。