3

我有以下宏:

(defmacro ss [x]

`(clojureql.core/select 
      (clojureql.core/table db "users_table")
      (clojureql.core/where  ~x)
  )
)

(macroexpand '(ss '(= :type "special")))

:但它产生:

(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where '(= :type "special"))) 

: 代替 :

(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where (= :type "special"))) 

:我意识到问题是我传入了一个列表'(=:type“special”),但是我怎样才能让它在宏中取消引用?

更新:

由于 Mikera 的回答,我终于得到了这个工作:

(defn ss [x]

  (clojureql.core/select 
      (clojureql.core/table db "users_table")
      x
  )


)

(macroexpand '(ss (eval `(clojureql.core/where ~'(= :type "special")))))

:虽然输出略有不同,但它按预期工作:

(ss (eval (clojure.core/seq (clojure.core/concat (clojure.core/list 'clojureql.core/where) (clojure.core/list '(= :type "special")))))) 
4

2 回答 2

3

在我看来,您将错误的东西传递给宏扩展:您可能应该使用:

(macroexpand '(ss (= :type "special")))

即你只需要在开头引用一个引号来引用整个表达式。

于 2011-07-07T19:40:02.287 回答
2

您不能将运行时参数传递给宏,因为前者仅在运行时才知道,而后者已经在编译时展开和编译。

你必须使用一个函数。

(defn get-users-by-type
  [t]
  (cql/select
    (cql/table db "users_table")
    (cql/where (= :type t))))
于 2011-07-08T07:24:53.363 回答