Могут ли принуждения карты быть установлены как делегаты? - PullRequest
0 голосов
/ 07 июня 2019

Я строю простой конструктор psuedo-xml, используя средства метапрограммирования Groovy во время выполнения.Я создал класс, который делает это успешно, однако, когда я попробовал другой подход, принудительно приведя карту к интерфейсу, я столкнулся с проблемами с устройством Groovy methodMissing.

Подходы, которые я пробовал, приводят ккарта с ключом methodMissing, содержащим Closure, в интерфейс с определенным methodMissing и GroovyObject

Вот основной:

mybuilder = new builder() //good
mybuilder.xml = { ->
    thelettersofdaalpabet {
        "q"
    }
}

mycoercionbuilder = new coercionbuilder() //errors out
mycoercionbuilder.messages = { ->
    thelettersofdaalpabet {
        "q"
    }
}

строитель (который работает):

class builder {
    def methodMissing(String methodName, args){
        println "<$methodName>"
        for(Closure c : args){
            c.delegate = this
            def out = c()
            if (out != null) println out
        }
        println "</$methodName>"
    }

    def propertyMissing(String propName, val) {
        this.methodMissing(propName,val)
    }
}

и coercionbuilder (с ошибками):

class coercionbuilder {
    def b = [
            methodMissing: { String methodName, args ->
                println "<$methodName>"
                for (Closure c : args) {
                    c.delegate = b
                    def out = c()
                    if (out != null) println out
                }
                println "</$methodName>"
            }] as builderrules //<-- I also changed this value to GroovyObject

    def propertyMissing(String propName, val) {
        this.b.methodMissing(propName, val)
    }
}

это интерфейс builderrules, упомянутый в coercionbuilder:

interface builderrules {
    def methodMissing(String methodName, args)
}

Когда карта принудительно приведенав построитель правил он выводит:

<xml>
<thelettersofdaalpabet>
q
</thelettersofdaalpabet>
</xml>
<messages>
Caught: groovy.lang.MissingMethodException: No signature of method: main.thelettersofdaalpabet() is applicable for argument types: (main$_run_closure2$_closure4) values: [main$_run_closure2$_closure4@ba47ffaf]
groovy.lang.MissingMethodException: No signature of method: main.thelettersofdaalpabet() is applicable for argument types: (main$_run_closure2$_closure4) values: [main$_run_closure2$_closure4@ba47ffaf]
    at main$_run_closure2.doCall(main.groovy:10)
    at coercionbuilder$_closure1.doCall(coercionbuilder.groovy:7)
    at com.sun.proxy.$Proxy14.methodMissing(Unknown Source)
    at builderrules$methodMissing.call(Unknown Source)
    at coercionbuilder.propertyMissing(coercionbuilder.groovy:14)
    at coercionbuilder.setProperty(coercionbuilder.groovy)
    at main.run(main.groovy:9)

когда карта приводится в GroovyObject и выводит:

<xml>
<thelettersofdaalpabet>
q
</thelettersofdaalpabet>
</xml>
Caught: java.lang.UnsupportedOperationException
java.lang.UnsupportedOperationException
    at com.sun.proxy.$Proxy14.invokeMethod(Unknown Source)
    at coercionbuilder.propertyMissing(coercionbuilder.groovy:14)
    at coercionbuilder.setProperty(coercionbuilder.groovy)
    at main.run(main.groovy:9)

1 Ответ

0 голосов
/ 08 июня 2019

Только стрельба с бедра, но вы пробовали установить стратегию разрешения закрытия на DELEGATE_FIRST:

...
                for (Closure c : args) {
                    c.delegate = b
                    c.resolveStrategy = Closure.DELEGATE_FIRST
                    def out = c()
                    if (out != null) println out
                }
...

...