如何使函数可用于 ClojureScript eval?

2024-04-02

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:

  1. 编译器分析元数据x需要出现在作为第一个参数传递的状态中cljs.js/eval。这样,在编译期间,诸如 arity 之类的事情x例如,已知。
  2. 关联函数的 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(使用前将#替换为@)

如何使函数可用于 ClojureScript eval? 的相关文章

随机推荐