mud*_*dge 10 java clojure clojure-contrib
无论如何从Java调用Clojure宏?
这是我想要做的:
RT.var("clojure.core", "require").invoke(Symbol.create("clojure.contrib.prxml"));
Var prxml = RT.var("clojure.contrib.prxml", "prxml");
Var withOutStr = RT.var("clojure.core", "with-out-str");
String stringXML = (String) withOutStr.invoke((prxml.invoke("[:Name \"Bob\"]")));
Run Code Online (Sandbox Code Playgroud)
prxml默认写入*out*,这就是为什么我需要用带有-out-str的宏包装它来返回字符串.
我收到此错误:
[java] java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$with-out-str
[java] at clojure.lang.AFn.throwArity(AFn.java:437)
[java] at clojure.lang.RestFn.invoke(RestFn.java:412)
[java] at clojure.lang.Var.invoke(Var.java:365)
[java] at JavaClojure.xml.main(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
你必须使用自己的onSutStr.
class YourClass {
static final Var withBindings = RT.var("clojure.core", "with-bindings*");
static final Var list = RT.var("clojure.core", "list*");
static final Var out = RT.var("clojure.core", "*out*");
static final Var prxml = RT.var("clojure.contrib.prxml", "prxml");
static String withOutStr(IFn f, Object args...) {
StringWriter wtr = new StringWriter();
withBindings.applyTo(list.invoke(RT.map(out, wtr), f, args));
return wtr.toString();
}
...
String stringXML = withOutStr(prxml, "[:Name \"Bob\"]");
}
Run Code Online (Sandbox Code Playgroud)
免责声明:我对 clojure 知之甚少(我的经验是使用其他函数式语言和 Java)
然而,我的直觉告诉我问题就在眼前prxml.invoke()。这里的想法是该语句计算得太早,并将结果发送到 withOutStr (而不是让 withOutStr 计算它)。
单独查看在线资源...特别是RT、Var和AFn以及with-out-str的 clojure 文档我会尝试以下内容:
String stringXML = (String) withOutStr.invoke(RT.list(prxml,"[:Name \"Bob\"]"));
Run Code Online (Sandbox Code Playgroud)
编辑:另外我怀疑它能够从java调用clojure宏,否则Var上的isMacro()函数看起来相当愚蠢......
编辑2:下载了clojure,并尝试了...不起作用,所以暂时忽略它。
编辑3:with-out-str显然需要2个参数,所以:
final Cons consXML = (Cons) withOutStr.invoke(prxml, RT.list("[:Name \"Bob\"]"));
final Object[] objs = RT.seqToArray(consXML);
System.out.println(Arrays.toString(objs));
Run Code Online (Sandbox Code Playgroud)
输出为:[clojure.core/let, [s__4095__auto__ (new java.io.StringWriter)], (clojure.core/binding [clojure.core/*out* s__4095__auto__] (clojure.core/str s__4095__auto__))]
我想知道这是否会评估出有用的东西,或者没有(不确定我的绑定是否正确,必须弄清楚如何通过Java评估缺点。
编辑 4:浏览编译器和更多代码,宏似乎实际上有 2 个隐藏参数。请参阅提交 17a8c90
在编译器中复制该方法我有:
final ISeq form = RT.cons(withOutStr, RT.cons(prxml, RT.cons("[:Name \"Bob\"]", null)));
final Cons consXML = (Cons) withOutStr.applyTo(RT.cons(form, RT.cons(null, form.next())));
System.out.println(consXML.toString());
// Output: (clojure.core/let [s__4095__auto__ (new java.io.StringWriter)] (clojure.core/binding [clojure.core/*out* s__4095__auto__] #'clojure.contrib.prxml/prxml "[:Name \"Bob\"]" (clojure.core/str s__4095__auto__)))
Run Code Online (Sandbox Code Playgroud)
这看起来更有希望,但它仍然需要对 let 表达式进行求值,这在编译器中似乎有一个特殊情况。
| 归档时间: |
|
| 查看次数: |
800 次 |
| 最近记录: |