我正在尝试使用Clojure解析一些Javascript库,以生成外部文件,以便在ClojureScript中使用它们。
我偶然发现并old Clojure source file打算执行此操作,但有一些已弃用的代码,不再有效,所以我想从中获取一些概念并重新开始。
从上面的Gists脚本开始,我开始使用读文件功能。
(ns n01se.externs-for-cljs
(:require [clojure.java.io :as io]
[cljs.compiler :as comp]
[cljs.analyzer :as ana]))
(defn read-file [file]
(let [eof (Object.)]
(with-open [stream (clojure.lang.LineNumberingPushbackReader. (io/reader file))]
(vec (take-while #(not= % eof)
(repeatedly #(read stream false eof)))))))
第一个问题:为什么eof由普通对象表示?
然后我将这个Javascript源代码提供给read-test-file
函数:
yayQuery = function() { // <= EXCEPTION: read exception at {
var yay = {};
yay.sayHello = function(message) {
console.log(message);
}
yay.getMessage = function() {
return 'Hello, world!';
}
return yay;
};
我启动了cider调试器并开始检查循环,并按预期得到yayQuery
。
所以我得到了:
在读者进入{
之前,会弹出此异常。
Map literal must contain an equal number of forms
。
假设:看起来read
函数试图解释{
,所以开始搜索密钥?
第二个问题:如果上述假设为真。我可以避免阅读评估代码吗?
我尝试将*read-eval*
绑定为false,但我仍然遇到相同的异常:
(ns externer.core
(:require [clojure.java.io :as io])
(:gen-class))
(defn read-test-file [file]
(let [eof (Object.)]
(with-open [stream (clojure.lang.LineNumberingPushbackReader. (io/reader file))]
(binding [*read-eval* false]
(take-while #(not= % eof)
(repeatedly #(read stream false eof)))))))
(defn -main
[& args]
(read-test-file (first args)))
由于edn,我也尝试了unsafety of using read,但我仍然遇到与上述相同的例外情况。
(ns externer.core
(:require [clojure.java.io :as io])
(:gen-class))
(defn read-test-file [file]
(let [eof (Object.)]
(with-open [stream (clojure.lang.LineNumberingPushbackReader. (io/reader file))]
(take-while #(not= % eof)
(repeatedly #(edn/read {:eof eof} stream))))))
(defn -main
[& args]
(read-test-file (first args)))
最后问题:还有另一种更安全/正确的方法可以自动生成外部电话吗?