더 나은 방법이있을 수 있지만 하나의 트릭은 직접 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();
}
이 그루비는 뒤에서하고있는 효과적으로 것입니다. delegate.identity
또는 owner.identity
을 사용할 수 없으므로 일반적인 트릭입니다.
편집 : 나는 무슨 일이 일어나고 있는지 알아 냈어.
Groovy adds a method 모든 개체에 identity(Closure c)
의 서명이 있습니다.
이
은 외부 폐쇄에
delegate({...})
를 호출처럼입니다
identity()
메소드를 호출하고, 하나의 폐쇄 인수를 전달하는 동안, 동적으로 XML 빌더에
identity
요소를 호출하려고 할 때 것을 의미한다.
invokeMethod
트릭을 사용하면 identity
메소드가 이미 MetaObject에 있어도 Groovy가 메타 오브젝트 프로토콜을 우회하여 동적 메소드로 강제 처리합니다.
이 사실을 알게되면 더 잘 읽고 더 쉽게 읽을 수있는 솔루션을 만들 수 있습니다.
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.invokeMethod ('identity')와 다른가? –
나는 그것을 알아 냈다. 나는 대답을 업데이트 할 것이다. – OverZealous
FYI : GroovyConsole을 사용하여 XML 객체를 검사하여 추적했습니다. 이것은'identity '메소드가 이미 하나의'Closure'를 인자로 사용하여 존재했다는 것을 알려줍니다. – OverZealous