Groovy ссылка на метод v3 и динамическая переменная groovyString c приоритет разрешения переменной, если вы явно задаете делегат MethodClosure - PullRequest
0 голосов
/ 02 марта 2020

Я использую Groovy v3.0.1.

Я вижу ответ, которого я не ожидал от следующего кода. Я строю карту глагола, существительного и замыканий.

Первый раз, когда я использую methodReference mybed::trySleep в качестве передаваемого замыкания, но устанавливаю делегат в качестве объекта данных и использую разрешение DELEGATE_ONLY.

Вторая запись передает прямое замыкание в строке как замыкание.

package playpen

class Bed {
    String name
    String bedSize = "5ft by 6ft"

    static sTrySleep () {
        println "called static on sleep"
    }

    void trySleep (arg = null) {
        println "called instance.onSleep() for name (${->name}) with " + arg ?: "<no arg>"
    }


}

Bed mybed = new Bed(name:"wills bed")

class DataObject {
    String name = "first data object"
    int height = 10
    int length = 12
    int width = 5
}

Map verbNounLookup = new HashMap()

Map buildAction (Map vnl, String verb, String noun, data, Closure method) {
    method.delegate = data
    method.resolveStrategy = Closure.DELEGATE_ONLY
    def lookup = [(verb): [(noun): method]]
    vnl.putAll(lookup)
    lookup
}

buildAction (verbNounLookup, "go", "snooze", new DataObject(), mybed::trySleep)
buildAction (verbNounLookup, "do", "thing", new DataObject(), {println "called with $it, and sees name as: $name"})

def action = verbNounLookup.go.'snooze'

action ("hi")

action = verbNounLookup.do.thing
action( "william")

Я представлял для первого поиска, что в качестве ссылки на метод динамически строит свою строку GString с помощью {-> name}, но делегат метода был переопределен для моего объекта данных, поэтому вызов этого метода разрешит имя объекта данных в качестве нового делегата.

Вторая запись, являющаяся моим внутренним закрытием, разрешает имя объекта данных делегата как вы ожидаете.

Это не так - вместо этого он разрешает имя в экземпляре myBed. Это правильное поведение?

Вывод:

called instance.onSleep() for name (wills bed) with hi 
called with william, and sees name as: first data object

1 Ответ

0 голосов
/ 03 марта 2020

MethodClosures не используют делегата, они являются указателем на метод, а просто вызывают метод прямо

это сообщение в списке рассылки )

MethodClosure похож на «указатель» на группу методов с заданным именем для данного экземпляра. Делегат не играет никакой роли в этом. Даже если это произойдет, после ввода метода применяются нормальные правила этого метода. А это значит, что процесс разрешения метода выполняется мета-классом класса, в котором метод определен в

...