(ns my-test
(:require blah))
(def foo 20)
(println (blah/magic))
这在clojure中效果很好,但在clojurescript中却没有(至少没有lein figwheel)。
我需要以下内容才能在Clojure和Clojurescript中工作。我认为宏是正确的解决方案,但我对其他技术持开放态度。
我想要一种将当前文件作为字符串读取的方法。例如,
(ns my-test
(:require blah))
(def foo 20)
(println (blah/magic))
然后应该导致(打印出来)
(println (slurp *file*))
如果我只需要在Clojure中使用它,我可以使用当前文件做有趣的事情并在运行时读取它。但是,我还需要在Clojurescript中工作(我不想设置一些REST API来提供* .cljs文件) - 因此,有没有办法在编译时通过一些宏来做到这一点? / p>
假设你想写一个"作弊的quine" - 你会怎么做?可能类似于DataArray
。现在,问题是什么?当在lein figwheel下运行时,这在clojurescript中不起作用。
答案 0 :(得分:3)
你需要像这样的Reader Conditionals:
(defn build-list []
(list #?@(:clj [5 6 7 8]
:cljs [1 2 3 4])))
请参阅此处的文档:
http://clojure.org/guides/reader_conditionals
https://github.com/clojure/clojurescript/wiki/Using-cljc
更新1
如果要修改当前正在执行的源代码,可以始终构造字符串并使用eval
:
(eval (read-string "(defn darth [] (println \"I have the ultimate power now...\" ))" ))
(darth)
;=> I have the ultimate power now...
然而,由于编译了ClojureScript,我不认为有任何简单的方法可以找到源原始源代码,如果这是你之后的事情。
更新2
这是一个有趣的问题。我最接近的是这样的:
(ns clj.core)
(defmacro fred [& forms]
(doseq [f forms]
(println `~f)))
(fred
(+ 1 2)
(* 2 3)
)
(defn -main [& args])
结果:
> lein run
(+ 1 2)
(* 2 3)
答案 1 :(得分:0)
在这里参加聚会很晚,但是我遇到了类似的问题,经过一天的搜索,我发现*file*
的ClojureScript对应词是cljs.analyzer/*cljs-file*
。
您还需要注意为宏创建仅宏的命名空间(除defmacro
外,什么都没有),并创建一个.clj文件。此外,根据我的经验,(:require-macros [your-macro-ns])
必须使用该名称空间,而不是普通的(:require ...)
。
所以您的问题的答案将是
(ns my-macro)
(defmacro compile-time-slurp-self []
(slurp cljs.analyzer/*cljs-file*))
(ns main
(:require-macros [my-macro]
(def foo 20)
(println (my-macro/compile-time-slurp-self))
应该注意的是,由于slurp需要Clojure,因此它仅适用于基于Clojure的ClojureScript编译器,而不适用于本身在ClojureScript上运行的新的自举式编译器。据我了解,后者主要用于基于浏览器的REPL和Java不可用的开发环境,只要您不在浏览器中构建代码,就可以了。