2012-08-31 29 views
1

我的目標是通過綁定執行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... ") 

沒有工作。後來我發現閉包是綁定的屬性,而不是方法。 有沒有什麼方法可以在這種情況下執行攔截以及如何執行攔截?元類的正確對象是什麼?注意,我的閉包在另一個嵌套閉包中執行。 感謝

+0

你試過* getProperty *嗎? http://groovy.codehaus.org/Using+invokeMethod+and+getProperty – Raphael

回答

0

我不知道這是否是更好的解決方案,但我能夠做到通過在結合

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

我也建議你拉法格的SlideShare上創建的DSL:

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

在這種SlideShare上,拉法格表示使用擴展腳本類結合;我認爲這是一個好方法。更多OO。

更新

看看mrhaki的建議,委託方法調用到基礎腳本類(也紀堯姆」 SlideShare上):

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

我只是用它來實現DSL over JFugue,它馬上就能工作。

+0

非常感謝。我在我的DSL中創建了嵌套結構,並且 – eugened

+0

它沒有與您的代碼一起工作,給我提供了MissingMethod異常。我還沒弄明白爲什麼。 Guilliame的slideshare非常豐富,並且使用與Groovy相同的示例來進行特定領域的語言書籍。感謝您的鏈接 – eugened

+0

你確定你沒有輸入錯誤的方法嗎?我的意思是,我寫的例子在groovy 2.0.1中工作 – Will