2014-10-07 3 views
3

내부 DSL을 만들고 DefaultGroovyMethods에서 any() 메서드를 오버로드합니다.Groovy DSL : 내부 DSL을 만들 때 Groovy에서 any()를 오버로드하는 방법

class RulesProcessor { 

} 

Any live cell with fewer than two live neighbours dies 

마지막 줄은 내 DSL입니다. 내가 propertyMissing, methodMissing, 내 모든 클래스, RulesProcessor.metaClass.any, DefaultGroovyMethods.metaClass.any를 만들려고했지만 그들은 작동하지 않습니다.

내 DSL을 허용하는 코드를 어떻게 작성할 수 있습니까? 'Any'단어가있는 첫 번째 단계 만 복잡합니다.

답변

2

당신이 폐쇄에 넣을 수 있다면, 내 예에서와 같이, any 방법에 응답하거나 객체, invokeMethod에 위임 :

당신이 파일에서 스크립트를 읽는 경우
class Dsl { 
    def params = [] 
    def invokeMethod(String method, args) { 
    params << [method, args] 
    this 
    } 

    def propertyMissing(String prop) { prop } 
} 


a = { 
    any live cell with fewer than two live neighbours dies 
} 


dsl = new Dsl() 
a.delegate = dsl 
a() 

assert dsl.params == [ 
    ['any', ['live']], 
    ['cell', ['with']], 
    ['fewer', ['than']], 
    ['two', ['live']], 
    ['neighbours', ['dies']], 
] 

, 명시 적으로 any라는 방법을 가지고하는 것은 필요한 것 같다 CompilerConfiguration에 mrhaki

import org.codehaus.groovy.control.CompilerConfiguration 

class Dsl { 
    def params = [] 
    def invokeMethod(String method, args) { 
    params << [method, args] 
    this 
    } 

    def any(param) { invokeMethod('any', [param]) } 

    def propertyMissing(String prop) { prop } 
} 

code = 'any live cell with fewer than two live neighbours dies' 

parsed = new GroovyShell(
    getClass().classLoader, 
    new Binding(), 
    new CompilerConfiguration(scriptBaseClass : DelegatingScript.class.name) 
).parse(code) 

dsl = new Dsl() 

parsed.setDelegate(dsl) 
parsed.run() 

assert dsl.params == [ 
    ['any', ['live']], 
    ['cell', ['with']], 
    ['fewer', ['than']], 
    ['two', ['live']], 
    ['neighbours', ['dies']], 
] 

했네.