在:2024 Clojure状态调查!中分享你的想法。

欢迎!请查看关于页面了解如何工作的更多信息。

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#)

...