は、より良い方法があるかもしれません、しかし、1つのトリックは、直接invokeMethod
を呼び出すことです:
String buildCatalog(Catalog catalog) {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
delegate.invokeMethod('identity', [{
groupId(catalog.groupId)
artifactId(catalog.artifactId)
version(catalog.version)
}])
}
return writer.toString();
}
これは、Groovyのは、舞台裏でやっている効果的にするものです。 delegate.identity
またはowner.identity
を正常に動作させることができませんでした。
編集:私は何が起こっている考え出しました。
Groovy adds a methodすべてのオブジェクトにidentity(Closure c)
の署名が付いています。
これは、動的にXMLビルダにidentity
要素を起動しようとしたとき、単一の閉鎖引数に渡しながら、それは外側の閉鎖にdelegate({...})
を呼び出すようなものですidentity()
メソッドを呼び出したことを意味します。
invokeMethod
トリックを使用すると、MetaObjectプロトコルがバイパスされ、identity
メソッドがすでにMetaObjectに存在していても、そのメソッドを動的メソッドとして扱うことができます。
これを知ると、わかりやすくわかりやすいソリューションをまとめることができます。
String buildCatalog(Catalog catalog) {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
// NOTE: LEAVE the empty map here to prevent calling the identity method!
identity([:]) {
groupId(catalog.groupId)
artifactId(catalog.artifactId)
version(catalog.version)
}
}
return writer.toString();
}
これは、はるかに読みやすいです、それは明確の意図、およびコメントは(たぶん)「不要」空を削除するから誰を防ぐ必要があります。私たちがしなければならないので、同様に、メソッドのシグネチャを変更で地図。
これはうまくいきましたが、これを説明できますか?デリゲートとは何ですか?また、delegate.identityとdelegate.invokeMethod( 'identity')との違いは何ですか? –
私はそれを理解した、私は私の答えを更新します。 – OverZealous
FYI:GroovyConsoleを使用してXMLオブジェクトを検査してこれを追跡しました。これは、単一の 'Closure'を引数として' identity'メソッドが既に存在していたことを私に知らせます。 – OverZealous