Clojure+;Clojurescript:读取当前文件代码的宏 我已经试过了

Clojure+;Clojurescript:读取当前文件代码的宏 我已经试过了,clojure,clojurescript,Clojure,Clojurescript,这在clojure中效果很好,但在clojurescript中却不行(至少在lein figwheel中不行) 原始问题 我需要在Clojure和Clojurescript中使用以下内容。我认为宏是正确的解决方案,但我对其他技术持开放态度 我想要一种将当前文件作为字符串读取的方法。比如说, (ns my-test (:require blah)) (def foo 20) (println (blah/magic)) 这将导致(被打印出来) 如果我只需要在Clojure中使用它,我就可

这在clojure中效果很好,但在clojurescript中却不行(至少在lein figwheel中不行)

原始问题 我需要在Clojure和Clojurescript中使用以下内容。我认为宏是正确的解决方案,但我对其他技术持开放态度

我想要一种将当前文件作为字符串读取的方法。比如说,

(ns my-test
  (:require blah))

(def foo 20)

(println (blah/magic))
这将导致(被打印出来)

如果我只需要在Clojure中使用它,我就可以对当前文件做一些有趣的事情,并在运行时读取它。然而,我也需要它在Clojurescript中工作(我不想设置一些RESTAPI来服务*.cljs文件)——因此,有什么方法可以在编译时通过一些宏来实现这一点吗

澄清
假设你想写一篇“欺骗奎因”——你会怎么做?可能类似于
(println(slurp*file*))
。现在,有什么问题吗?在lein figwheel下运行时,这在clojurescript中不起作用。

您需要这样的读卡器条件:

(defn build-list []
  (list #?@(:clj  [5 6 7 8]
            :cljs [1 2 3 4])))
(ns clj.core)

(defmacro fred [& forms]
  (doseq [f forms]
    (println `~f)))

(fred 
  (+ 1 2)
  (* 2 3)
)

(defn -main [& args])
请参见此处的文档:

更新1

如果要修改当前正在执行的源代码,可以始终构造字符串并使用
eval

(eval (read-string "(defn darth [] (println \"I have the ultimate power now...\" ))" ))

(darth)
;=> I have the ultimate power now...
然而,由于ClojureScript是编译的,我认为没有任何简单的方法可以找到源代码,如果这是您想要的

更新2

这是一个有趣的问题。我最近的一次是这样的:

(defn build-list []
  (list #?@(:clj  [5 6 7 8]
            :cljs [1 2 3 4])))
(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)

很晚才来到这里参加聚会,但我遇到了类似的问题,经过一天的搜索,我发现与
*文件*
对应的ClojureScript是
cljs.analyzer/*cljs文件*

您还需要小心地为宏创建一个仅宏的名称空间(除了
defmacro
s之外没有其他名称空间),并将其设置为.clj文件。此外,根据我的经验,这个名称空间必须是
(:require macros[your macro ns])
所必需的,而不是普通的
(:require…

所以你的问题的答案是

my_macro.clj main.cljs
应该注意的是,由于slurp需要Clojure,因此这只适用于基于Clojure的ClojureScript编译器,而不是在ClojureScript上运行的新的引导编译器。据我所知,后者主要用于基于浏览器的REPL和dev环境,在这些环境中,Java不可用,因此只要您不在浏览器中构建代码,您就可以了。

您需要做什么才能使slurp和spit不适合您?@jmargolisvt:当前文件的名称。在clojure中,我可以通过file获得当前文件的名称——在cljs中,似乎有一些古怪的事情正在发生。你能举个例子说明你想做什么吗?@AlanThompson:我上面的例子写得很糟糕。上面的内容应该是一个作弊的“奎因”——一个自动打印的程序。@AlanThompson:上面的澄清有意义吗?(很抱歉这个问题让人困惑)。我以前使用过reader条件句,它们是C的Iffefs的clojure等价物——但是,我不清楚它们在这个问题中的相关性。1)谢谢你的耐心2)我仍然认为我没有正确地解释这个问题。有意义吗?因为CLJS是编译(成javascript)的,所以您不能真正执行
slurp
。因此,当它运行时,只有编译后的JS代码可用,而不是CLJS源代码。我同意在运行时,这是不可能的。因此,我希望玩一些宏魔术,并在编译时执行。:-)也许你应该发邮件给作者,他可能有一些改进的好主意。向Clojure Google groups邮件列表发送电子邮件也是一个好主意。编译此邮件的命令是什么?我在(REPL:1)编译时遇到错误`clj-mcljs.main--optimizations advanced-c hello\u world.core意外错误(FileNotFoundException)。在类路径上找不到my_macro_uinit.class、my_macro.clj或my_macro.cljc。请检查带有破折号的命名空间是否在Clojure文件名中使用下划线。“可能只是my-macro.clj需要命名为my_macro。
(ns my-macro)

(defmacro compile-time-slurp-self []
  (slurp cljs.analyzer/*cljs-file*))
(ns main
  (:require-macros [my-macro]))

(def foo 420)

(println (my-macro/compile-time-slurp-self))