将对象从java传递到Clojure eval
我从Java调用Clojure,并对传入的字符串调用将对象从java传递到Clojure eval,clojure,eval,Clojure,Eval,我从Java调用Clojure,并对传入的字符串调用eval。Java代码将保存对象,客户机代码可以指定要在对象上运行的Clojure代码字符串。我知道如何从Java调用Clojure代码,但如何传入变量 这是我的。首先,要处理的简单对象: public class Helloer { public String getGreeting() { return "Hello"; } } 然后使用一些样板代码来调用Clojure方法 public static String call(He
eval
。Java代码将保存对象,客户机代码可以指定要在对象上运行的Clojure代码字符串。我知道如何从Java调用Clojure代码,但如何传入变量
这是我的。首先,要处理的简单对象:
public class Helloer {
public String getGreeting() { return "Hello"; }
}
然后使用一些样板代码来调用Clojure方法
public static String call(Helloer helloer, String expression) throws Exception {
RT.loadResourceScript("EvalObject.clj");
final Var schrodEval = RT.var("eval-object", "eval-string");
final String result = (String) schrodEval.invoke(expression, helloer);
return result;
}
但后来我被Clojure密码卡住了。对象可以很好地传入,但是如何将值传入eval
以下是我尝试过的:
(ns eval-object)
(defn eval-string [string this]
(eval (read-string string)))
(defn eval-string2 [string value]
(def this)
(binding [this value]
(eval (read-string string))))
(defn eval-string3 [string value]
(def this)
(eval (list 'binding (vector 'this 5) (read-string string))))
这些建议包括:
java.lang.Exception: Unable to resolve symbol: this in this context (NO_SOURCE_FILE:0)
然后我尝试构造一个绑定子句来定义这个:
(defn eval-string4 [string value]
(def this)
(eval (list 'do (list 'defonce 'this nil)
(list 'binding (vector 'this value) (read-string string)))))
但现在我明白了:
java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: Helloer@638bd7f1 (NO_SOURCE_FILE:0)
我错过什么了吗?是否可以将对象从Java传递到Clojure并传递到eval?还不完全清楚“将对象传递到eval”是什么意思。也许你可以进一步澄清一下目标 然而,您可能正在寻找类似以下内容:
(defn call-eval [helloer]
(eval `(.getGreeting ~helloer)))
(call-eval some-helloer)
=> "Hello"
有几件事需要注意:
- 进行评估时,您需要引用表格
- 要传入“对象”,您需要在此表单中将其解压缩(
),以便直接使用对象,而不仅仅是作为符号使用~
- 您不需要eval,因为
同样有效(而且效率更高,因为它不需要编译表单。通常,只有在运行时动态生成新代码时,或者如果您想读入并接受任意代码作为输入(例如REPL本身),才需要eval(.getGreeting helloer)
打印dup
。我为Helloer
类实现了一个简单的ID查找,并将打印dup
定义为:
(defmethod print-dup com.ziroby.Helloer [h stream]
(.write stream "#=(com.ziroby.Helloer/getById ")
(.write stream (str (.getId h)))
(.write stream ")"))
显然,Clojure需要某种方式打印对象才能将其放入eval语句中。此print dup
创建Clojure语句,通过Helloer.getById
查找对象来“创建”该对象(仅在hashmap中查找对象)
正如@mikera所说,如果您正在接受来自调用方的任意代码或动态生成代码,则只需跳过这些环。我正在执行eval的第二种情况。我希望读入并接受任意代码。我希望任意代码能够以
this
的形式访问helloer
对象。