In 德米特里·索特尼科夫 (Dmitri Sotnikov) 的这篇博文 http://yogthos.net/posts/2015-11-12-ClojureScript-Eval.html一个函数eval-str
提供用于运行包含 ClojureScript 的字符串:
(defn eval-str [s]
(eval (empty-state)
(read-string s)
{:eval js-eval
:source-map true
:context :expr}
(fn [result] result)))
如果我有一些功能x
我希望能够从 eval 字符串内部调用,我该怎么做?
答案有两部分,假设x
是与 ClojureScript 函数关联的 var:
- 编译器分析元数据
x
需要出现在作为第一个参数传递的状态中cljs.js/eval
。这样,在编译期间,诸如 arity 之类的事情x
例如,已知。
- 关联函数的 JavaScript 实现
x
需要存在于 JavaScript 运行时中。 (如果该函数实际上是called在此期间cljs.js/eval
调用,而不仅仅是引用。)
If x
是一个核心函数(比如 var#'cljs.core/map
例如),那么这两个条件都会自动满足。特别是,元数据将在以下情况下生成:cljs.js/empty-state
被称为(假设:dump-core https://clojurescript.org/guides/self-hosting is true
),并且核心函数的实现已经被加载到 JavaScript 运行时中。
但是,我们说x
是您希望在自托管环境中编译的全新函数。 “技巧”是设置和重用编译器状态:例如将结果(cljs.js.empty-state)
放入 var 中,并将其传递给每个cljs.js/eval
称呼。如果你这样做,并且其中之一cljs.js/eval
调用涉及编译一个defn
for x
,那么编译器状态将为modified(它实际上是一个原子),结果是编译器元数据x
将会被放入状态,当然还有 JavaScript 实现x
在 JavaScript 环境中设置(通过评估为defn
).
另一方面,如果x
是“环境”ClojureScript 环境的一部分的函数(例如,通过 JVM ClojureScript 编译器预编译,但仍然可以在 JavaScript 运行时使用),那么您将需要以某种方式安排获得编译器分析元数据x
进入状态传递给cljs.js/eval
。如果您查看基于 JVM 的编译器的输出,您将看到<ns-name>.cache.json
包含此类元数据的文件。查看这些文件中的数据,您可以确定其结构;这样您就可以看到如何将所需的信息交换到编译器状态中[:cljs.analyzer/namespaces <ns-name>]
. The cljs.js/load-analysis-cache!
函数作为此用例的助手而存在,一个独立的示例位于https://stackoverflow.com/a/51575204/4284484 https://stackoverflow.com/a/51575204/4284484
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)