我正在尝试使用Clojure作为来自主机Java程序的脚本语言。这样做的目的是,最终用户将能够编写能够调用特定于域的Java的Clojure脚本代码。在运行时,主机Java程序将评估最终用户的Clojure脚本(然后调用域API)。所以我开始用一个非常简单的原型来探索地形。
域名
package a.problem.domain;
public class Domain {
public Domain() { }
public String defaultMsg() {
return "default";
}
public String passBackMsg(String s) {
return s;
}
}主机Java程序
(为了简单起见,最终用户的Clojure脚本硬编码)
String script = "(do "+
" (import '(a.problem.domain Domain)) "+
" (.defaultMsg (Domain.)) "+
") ";
System.out.println(RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script)));(代码片段摘自这里)
到目前一切尚好。
但是,我找不到一种方法来调用第二个方法(需要一个参数的方法)。相反,我求助于在运行时动态生成Clojure脚本,并将占位符替换为表示调用域方法passBackMsg的结果的文字。显然,这是不能令人满意的,而且不会太远(如果我想将一个java.sql.Connection传递给我的Clojure脚本怎么办?)
那么,如何从主机程序调用passBackMsg方法呢?
当我尝试以下几点时:
String script = "(ns foo) "+
"(import '(a.problem.domain Domain)) "+
"(defn numberToString [s] ( "+
" (.passBackMsg (Domain.) s) "+
")) ";
RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script)); // line-A
System.out.println(RT.var("foo", "numberToString").invoke(33)); // line-B我得到:
java.lang.IllegalStateException: Can't change/establish root binding of: *ns* with set..。在线-A。当我试着不带ns的时候
RT.var("user", "numberToString").invoke(33)("user“是一个疯狂的猜测,因为我没有看到没有名称空间参数的var方法)
我得到了一个:
java.lang.IllegalStateException: Attempting to call unbound fn: #'user/numberToString"..。在线-B。
发布于 2013-02-21 08:18:13
试试这个:
String script = "(do "+
" (import '(a.problem.domain Domain)) "+
" (fn [s] " +
" (.passBackMsg (Domain.) s) "+
")) ";
IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script));
fn.invoke("hello");更新:示例代码下面的运行良好:
package hello_clj;
import clojure.lang.RT;
import clojure.lang.IFn;
public class Main {
public String passBackMsg(String s) {
return s;
}
public static void main(String[] args) {
String script = "(do (import 'hello_clj.Main) (fn [s] " +
"(.passBackMsg (Main.) s) ))";
IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script));
System.out.print(fn.invoke("Hello"));
}
}https://stackoverflow.com/questions/14987910
复制相似问题