Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将对象从java传递到Clojure eval_Clojure_Eval - Fatal编程技术网

将对象从java传递到Clojure eval

将对象从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

我从Java调用Clojure,并对传入的字符串调用
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,因为
    (.getGreeting helloer)
    同样有效(而且效率更高,因为它不需要编译表单。通常,只有在运行时动态生成新代码时,或者如果您想读入并接受任意代码作为输入(例如REPL本身),才需要eval

结果表明错误消息是正确的。我需要定义
打印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
对象。