如何使函数可用于ClojureScript的评估? [英] How can I make functions available to ClojureScript's eval?

查看:82
本文介绍了如何使函数可用于ClojureScript的评估?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Dmitri Sotnikov的此博客帖子中提供了 eval-str 来运行包含ClojureScript的字符串:

In this blog post by Dmitri Sotnikov a function eval-str is provided for running a string containing ClojureScript:

(defn eval-str [s]
  (eval (empty-state)
        (read-string s)
        {:eval       js-eval
         :source-map true
         :context    :expr}
        (fn [result] result)))

如果我想在eval字符串中调用某些函数 x ,我该怎么做?

If I have some function x that I want to be able to call from inside the eval string, how can I do that?

推荐答案

答案有两部分,假设 x 是与ClojureScript函数关联的变量:

There are two parts to the answer, assuming x is a var associated with a ClojureScript function:


  1. x 的编译器分析元数据必须以通过的状态存在作为 cljs.js / eval 的第一个参数。这样一来,在编译过程中,例如,会知道 x 的Arity之类的东西。

  2. 该函数的JavaScript实现与 x 关联的代码需要出现在JavaScript运行时中。 (尤其是如果在 cljs.js / eval 调用期间实际上是调用的函数,而不仅仅是引用了该函数。)

  1. The compiler analysis metadata for x needs to be present in the state passed as the first argument to cljs.js/eval. This is so that, during compilation, things like the arity of x is known, for example.
  2. The JavaScript implementation of the function associated with x needs to be present in the JavaScript runtime. (This is especially true if the function is actually called during the cljs.js/eval call, and not just referenced.)

如果 x 是核心功能(例如var #'例如clcl.core / map ),那么这两个条件都会自动满足。特别地,元数据将在调用 cljs.js / empty-state 时生成(假设 :dump-core true ),并且实现

If x is a core function (say the var #'cljs.core/map for example), then both of these conditions is automatically satisfied. In particular, the metadata will be produced when cljs.js/empty-state is called (assuming :dump-core is true), and the implementation of the core functions will have already been loaded into the JavaScript runtime.

但是,可以说 x 完全是您希望在自托管环境中编译的新函数。 技巧是建立并重新使用编译器状态:例如,将(cljs.js.empty-state)的结果放入var中,并将其传递给每个 cljs.js / eval 调用。如果这样做,则 cljs.js / eval 调用之一涉及为<$ c $编译 defn c> x ,那么编译器状态将被修改(实际上是一个原子),结果是 x 会进入状态,当然还会在JavaScript环境中设置 x 的JavaScript实现(通过评估JavaScript

But, let's say x is a wholly new function that you wish to have compiled in the self-hosted environment. The "trick" is to set up and reuse compiler state: For example put the result of (cljs.js.empty-state) into a var, and pass it to every cljs.js/eval call. If you do that, and one of the cljs.js/eval calls involves compiling a defn for x, then the compiler state will be modified (it is actually an atom), with the result being that the compiler metadata for x will be put in the state, along with, of course, the JavaScript implementation for x being set within the JavaScript environment (by virtue of evaluating the JavaScript produced for the defn).

如果另一方面, x 是属于环境 ClojureScript环境(例如,已通过JVM ClojureScript编译器预编译,但仍可在JavaScript运行时中使用)的一部分的函数,然后由您决定如何安排使 x 的编译器分析元数据进入传递给 cljs.js / eval 的状态。如果查看基于JVM的编译器的输出,将会看到包含此​​类元数据的< ns-name> .cache.json 文件。查看这些文件中的数据,然后可以确定其结构;这样,您可以在 [:cljs.analyzer / namespaces< ns-name>] 下查看如何将所需的信息转换为编译器状态。 cljs.js / load-analysis-cache!函数作为此用例的帮助程序存在,并且一个独立的示例位于https://stackoverflow.com/a/51575204/4284484

If, on the other hand, x is a function that is part of your "ambient" ClojureScript environment (say, pre-compiled via the JVM ClojureScript compiler, but nevertheless available in the JavaScript runtime), then it will be up to you to somehow to arrange to get the compiler analysis metadata for x into the state passed to cljs.js/eval. If you look at the output of the JVM-based compiler, you will see <ns-name>.cache.json files containing such metadata. Take a look at the data that is in these files and you can ascertain its structure; with that you can see how to swap the needed information into the compiler state under [:cljs.analyzer/namespaces <ns-name>]. The cljs.js/load-analysis-cache! function exists as a helper for this use case, and a self-contained example is at https://stackoverflow.com/a/51575204/4284484

这篇关于如何使函数可用于ClojureScript的评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆