2011-12-13 7 views
2

Groovy에서 흐름을 표현하기위한 DSL을 작성하고 있습니다. 플로우의 특정 지점에서 저장되고 평가되는 함수를 작성할 수있는 기능을 사용자에게 제공하고자합니다. 다음과 같이하십시오 :groovy 스크립트가 포함 된 Groovy DSL

states { 
    "checkedState" { 
     onEnter {state-> 
      //do some groovy things with state object 
     } 
    } 
} 

자, 저는 닫힌 부분을 따옴표로 묶고 저장할 수 있다고 확신합니다. 그러나이 DSL을 편집 할 때 가능한 경우 구문 강조 및 콘텐츠 지원을 유지하고 싶습니다. 클로저가 다른 컨텍스트에서 클로저를 실행할 때 더 이상 유효하지 않은 주변 흐름 정의에서 클로저가 참조 할 수있는 참조 아티팩트가 있다는 것을 알았습니다. 실제로 클로저 구문을 클로저가 아닌 함수 정의에 사용하고 싶습니다.

tl; dr; DSL을 데이터베이스에 저장하고 나중에 스크립트 호스트에서 실행할 수 있도록 DSL을 평가하는 동안 클로저의 코드를 가져와야합니다.

답변

2

클로저의 소스 코드를 얻는 방법이 없다고 생각합니다.이 정보는 컴파일 중에 버려집니다. 아마도 클로저의 구문 트리를 런타임에 사용할 수 있도록 AST transformation을 작성할 수 있습니다.

클로저를 데이터베이스에 저장하고 나중에 소스 코드에 액세스 할 필요가 없다면 직렬화하고 직렬화 된 형식을 저장할 수 있습니다.

ClosureSerializable를 구현하고 owner, thisObjectdelegate 특성을 제로 화시키는 후 나는 그것을 직렬화 할 수 있었다, 그러나 나는 직렬화에 ClassNotFoundException을 얻고있다.

def myClosure = {a, b -> a + b} 

Closure.metaClass.setAttribute(myClosure, "owner", null) 
Closure.metaClass.setAttribute(myClosure, "thisObject", null) 
myClosure.delegate = null 

def byteOS = new ByteArrayOutputStream() 
new ObjectOutputStream(byteOS).writeObject(myClosure) 
def serializedClosure = byteOS.toByteArray() 

def input = new ObjectInputStream(new ByteArrayInputStream(serializedClosure)) 
def deserializedClosure = input.readObject() // throws CNFE 

일부를 검색 한 후, I는 Groovy Remote Control 클로저를 직렬화 및 가능한 원격 시스템에서, 나중에 실행 가능하도록 특별히 제작 라이브러리 알았다. 시도 해보십시오. 아마도 당신이 필요로하는 것입니다.

+0

대단히 감사합니다! 미리 작성된 AST 렌더링 라이브러리의 부족으로이 답변이 이길 것입니다. 그러나 다른 사람들이 대답 할 수있는 시간을 조금 더 갖도록하겠습니다. –