Clojure 2024年调查问卷中分享您的想法!

欢迎!请查看关于页面以获得更多关于其工作方式的详细信息。

0
ClojureScript

我有这个宏

(defmacro log
  "Take any number of expressions. For each expression print 'expr=value' on
  js/console. For self-evaluating expressions (eg. keywords, strings) omit
  the 'expr=' part. Each expression is only evaluated once."
  [& exprs]
  `(let [evaluated# (list ~@exprs)
         lst# (map #(if (= %1 %2)
                      (list %2)
                      (list %1 %2))
                   '~exprs
                   evaluated#)]
     (.log js/console lst#)))

它是这样计算的

background:cljs.user=> (log :a (+ 1 2) js/console)
;; => nil
;; js/console output => ((:a) (▶(…) 3) (js/console ▶#js {…}))

宏展开看起来像这样

background:cljs.user=> (macroexpand '(log :a (+ 1 2) js/console))
(let*
 [evaluated__55571__auto__
  (clojure.core/list :a (+ 1 2) js/console)
  lst__55572__auto__
  (clojure.core/map
   (fn*
    [p1__55569__55573__auto__ p2__55570__55574__auto__]
    (if
     (clojure.core/= p1__55569__55573__auto__ p2__55570__55574__auto__)
     (clojure.core/list p2__55570__55574__auto__)
     (clojure.core/list
      p1__55569__55573__auto__
      p2__55570__55574__auto__)))
   '(:a (+ 1 2) js/console)
   evaluated__55571__auto__)] 
 (.log js/console lst__55572__auto__))

我想消除输出中的冗余括号。我怎样才能将lst#的元素拼接到.log宏中?我不能使用apply,因为.log不是一个函数,并且 (.log js/console ~@lst#) 也不工作。

我还想能够在控制台上展开结果中的对象,所以我不能将所有内容都转换为字符串,并将其作为一个大字符串传递给.log。

1 个答案

+2

入选
 
最佳答案

尝试使用JavaScript自己的apply方法,例如

(.apply js/console.log js/console lst#)

...