首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java -> Clojure ->

Java -> Clojure ->
EN

Stack Overflow用户
提问于 2013-02-20 19:04:49
回答 1查看 1.1K关注 0票数 7

我正在尝试使用Clojure作为来自主机Java程序的脚本语言。这样做的目的是,最终用户将能够编写能够调用特定于域的Java的Clojure脚本代码。在运行时,主机Java程序将评估最终用户的Clojure脚本(然后调用域API)。所以我开始用一个非常简单的原型来探索地形。

域名

代码语言:javascript
复制
package a.problem.domain;

public class Domain {

    public Domain() { }

    public String defaultMsg() {
        return "default";
    }

    public String passBackMsg(String s) {
        return s;
    }
}

主机Java程序

(为了简单起见,最终用户的Clojure脚本硬编码)

代码语言:javascript
复制
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方法呢?

当我尝试以下几点时:

代码语言:javascript
复制
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

我得到:

代码语言:javascript
复制
java.lang.IllegalStateException: Can't change/establish root binding of: *ns* with set

..。在线-A。当我试着不带ns的时候

代码语言:javascript
复制
RT.var("user", "numberToString").invoke(33)

("user“是一个疯狂的猜测,因为我没有看到没有名称空间参数的var方法)

我得到了一个:

代码语言:javascript
复制
java.lang.IllegalStateException: Attempting to call unbound fn: #'user/numberToString"

..。在线-B。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-21 08:18:13

试试这个:

代码语言:javascript
复制
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");

更新:示例代码下面的运行良好:

代码语言:javascript
复制
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"));
    }

}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14987910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档