使用 clojure 作为脚本语言时如何添加 Java 实例作为上下文?

How to add a Java instance as context when using clojure as a scripting language?

我发现了一个非常有用的问题 How can I use clojure as scripting language for a Java program?,但我不知道如何将现有的 Java 实例添加到 Clojure 中。用例与 AutoCad 的 AutoLisp 非常相似。我想让用户使用脚本来操作应用程序,这样他们就可以在没有我的帮助或输入的情况下自由地做更多的事情。我想要一个 class 做一些工作

public class Testing {
    public void work() {
        // ....
    }
}

然后将其添加到 Clojure

public class Main {
    public static void main() {
        Testing t = new Testing()
        IFn eval = Clojure.var("clojure.core", "eval");
        System.out.println(eval.invoke(Clojure.read("(import Testing)")));
        // How do i get "t" into clojure?
        System.out.println(eval.invoke(Clojure.read("(.work t)")));
    }
}

但是我不知道怎么做。我似乎无法使用来自 java 的参数调用 def。我一直在摆弄这个和文档有一段时间了,但似乎无法弄清楚。

import clojure.java.api.Clojure;
import clojure.lang.Var;
import clojure.lang.RT;
import clojure.lang.Compiler;


public class Main {
    public static void main(String[] _argv) {
        // Using String instead of Testing just to avoid having to
        // deal with multiple files during compilation.
        String s = "Hello there";

        // Needed to allow creating new namespaces.
        // If you ever get stuck with some functionality not working, check out
        // Compiler.load - there are other bindings in there which, I guess, might be important.
        // So you can either copy all the bindings here or simply use Compiler.load instead of
        // Compiler.eval for script pieces that don't require bindRoot.
        Var.pushThreadBindings(RT.mapUniqueKeys(RT.CURRENT_NS, RT.CURRENT_NS.deref()));
        try {
            Compiler.eval(Clojure.read("(ns user)"));
            // def returns the var itself.
            ((Var) Compiler.eval(Clojure.read("(def s)"))).bindRoot(s);

            Compiler.eval(Clojure.read("(println s \"in\" (ns-name *ns*)))"));
        } finally {
            Var.popThreadBindings();
        }
    }
}