我在Clojure项目中使用SnakeYAML Java库。我想在Clojure中使用以下内容:
class DiceConstructor extends SafeConstructor {
public DiceConstructor() {
this.yamlConstructors.put(new Tag("!dice"), new ConstructDice());
}
private class ConstructDice extends AbstractConstruct {
public Object construct(Node node) {
String val = (String) constructScalar((ScalarNode) node);
int position = val.indexOf('d');
Integer a = new Integer(val.substring(0, position));
Integer b = new Integer(val.substring(position + 1));
return new Dice(a, b);
}
}
}
解释:我想创建一个SafeConstructor
的子类来访问其超类的受保护字段yamlConstructors
,并将AbstractConstruct
的一些自定义子类添加到yamlConstructors
我正在考虑使用proxy
,但似乎代理无法访问受保护的字段。还有其他可能性吗?
答案 0 :(得分:1)
我最终使用clojure.contrib.reflect中的方法,如下所示:
(require '[clojure.contrib.reflect :as reflect])
(defn dice-constructor
"Creates a custom SafeConstructor that understands the !dice tag"
[]
(let [result (SafeConstructor.)
constructor (proxy [AbstractConstruct] []
(construct [node]
(let [scalar-node (cast ScalarNode node)
scalar (reflect/call-method BaseConstructor 'constructScalar [ScalarNode] result scalar-node)
string-val (cast String scalar)]
(println (str "Loading: " string-val)))))]
(.put (reflect/get-field BaseConstructor 'yamlConstructors result)
(Tag. "!dice")
constructor)
result))
答案 1 :(得分:0)
通常,如果你不能使用proxy
因为你需要生成一个命名类,那么gen-class就是下一个选项。这需要更多的工作,并且结果更灵活。