在这个 2024年Clojure状态调查 中分享您的想法!

欢迎!请参阅关于页面了解有关如何使用本网站的更多信息。

0
ClojureScript
我的理解是,一个命名空间必须自己 {{:require-macros}} 才能使其宏自动可访问,但这一点现在似乎不再准确。

给定的这个最小例子:

;; src/demo/lib.cljs
(ns demo.lib)

;; src/demo/lib.clj
(ns demo.lib)

(defmacro foo [& args]
  `(prn ::macro))

;; src/demo/test.cljs
(ns demo.test
  (:require [demo.lib :as lib]))

(lib/foo 1 2 3)


我原本期望对于 {{lib/foo}} 有警告,因为 {{demo.lib}} 没有为它的宏声明 {{:require-macros}},而 {{demo.test}} 也没有使用 {{:include-macros}} 或 {{:refer-macros}}。

通过构建API编译确实产生了预期的警告,但前提是 {{demo.lib}} 的 CLJ 命名空间没有被其他地方所引用。


警告:使用了未声明的变量 demo.lib/foo,位于 src/demo/test.cljs 第5行



;; build.clj

(require '[cljs.build.api :as cljs])
;; (require 'demo.lib) ;; 在这里引用它将移除警告

(cljs/build
  "src"
  {:output-dir "out"
   :optimizations :none
   :verbose true})


在 build.clj 中启用 {{(require 'demo.lib)}} 可使警告消失,代码也正确使用宏。

一些流行的库(例如 devcards)没有自我引用,但如果宏文件至少在其他地方被引用了也能正常工作。

这是预期的行为,还是偶然的?

3 答案

0

评论者:dnolen

在某种程度上,这是意外的 - 宏解析简单到有点天真。我不确定我们现在是否应该对此采取任何措施。这可能会导致很多破坏而带来的好处很少。

0

评论者:mfikes

见CRRBV-19

0
参考:https://clojure.atlassian.net/browse/CLJS-2454(由 thheller 报告)
...