Перехват вызова закрытия в объекте привязки при выполнении скрипта groovy

Моя цель - выполнить скрипт groovy с привязкой, где функции предопределены, а время выполнения перехватчика выходит из системы и результат оценки закрытия. Мой пример кода:

  binding.login = { ->
     binding.event.appname=='login'
  }  def gse = new GroovyScriptEngine("src/main/resources/rules")
  gse.run('DSL.groovy', binding)

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

  Binding.metaClass.invokeMethod = { String name, args ->
                       println ("Call to $name intercepted... ")

не работает. Позже я понял, что замыкание — это свойство привязки, а не метод. Есть ли способ выполнить перехват в этом сценарии и как это сделать? Что было бы правильным объектом для метакласса? Следует отметить, что мое закрытие выполняется внутри другого вложенного закрытия. Спасибо


person eugened    schedule 31.08.2012    source источник
comment
Вы пробовали getProperty? groovy.codehaus.org/Использование+invokeMethod+and+getProperty   -  person Raphael    schedule 31.08.2012


Ответы (1)


Я не знаю, лучшее ли это решение, но мне удалось сделать то, что вы хотели, украсив застежки в переплете.

binding = new Binding([
    login : { -> println "binding.login called" },
    echo : { String text -> println "test for $text" },
    foo : { a, b, c -> println "$a $b $c" }
])


binding.variables.each { key, value ->
    if (value instanceof Closure) 
    {
        binding.variables[key] = { Object[] args -> 
            long t0 = System.currentTimeMillis()

            value( *args )

            print "[$key method"
            print " args: $args "
            println " time: ${System.currentTimeMillis() - t0}]"
        }
    }
}


def gse = new GroovyScriptEngine(".")

gse.run('Bind.groovy', binding)

А это мой Bind.groovy:

println " ** executing bind"
login()
echo("echo")
foo("test", 4, "echo")
println " ** bind script done"

Вы также можете попробовать/поймать MissingMethodException, если вы не определили метод как замыкание в привязке.

Я также рекомендую вам слайд-шоу Laforge при создании DSL:

http://www.slideshare.net/glaforge/going-to-mars-with-groovy-domainspecific-languages

В этом слайде Лафорж показывает привязку с использованием класса, который расширяет скрипт; я думаю, что это хороший подход. Еще ОО.

Обновить

Взгляните на предложение mrhaki делегировать вызовы методов базовому классу Script (также в слайд-шоу Гийома):

http://mrhaki.blogspot.com.br/2011/11/groovy-goodness-create-our-own-script.html

Я только что использовал его для реализации DSL через JFugue, и он сразу же заработал.

person Will    schedule 31.08.2012
comment
Большое Вам спасибо. Я создал вложенные структуры в своем DSL и - person eugened; 03.09.2012
comment
он не работал с вашим кодом, что дало мне исключение MissingMethod. Я еще не понял, почему. Слайд-шоу Guilliame очень информативно и использует тот же пример, что и в книге Groovy для предметно-ориентированных языков. Спасибо за ссылки - person eugened; 03.09.2012
comment
Вы уверены, что не набрали метод неправильно? Я имею в виду, что примеры, которые я написал, работали здесь в groovy 2.0.1. - person Will; 03.09.2012