Прихващане на повикване за затваряне в обвързващ обект при изпълнение на 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/Using+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

В това споделяне на слайдове Laforge показва обвързване с помощта на клас, който разширява скрипта; мисля, че това е добър подход. Още OO.

Актуализация

Обърнете внимание на предложението на mrhaki за делегиране на извиквания на метод към базов клас Script (също в споделянето на слайдове на Guillaume):

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