带有嵌入式 Groovy 脚本的 Groovy DSL

发布于 2024-12-21 04:21:56 字数 432 浏览 1 评论 0原文

我正在编写一个 DSL,用于在 groovy 中表达流程(我知道的原始内容)。我想为用户提供编写在流程中的某些点存储和评估的函数的能力。就像:

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

现在,我很确定我可以用引号将闭包括起来并存储它。但如果可能的话,我希望在编辑这些 DSL 时保留语法突出显示和内容辅助。我意识到闭包可以引用周围流定义中的工件,当在不同的上下文中执行闭包时,这些工件将不再有效,我对此很满意。实际上,我想使用闭包语法来定义非闭包函数。

太长;博士;我需要在评估 DSL 时获取闭包的代码,以便将其存储在数据库中并稍后由脚本主机执行。

I am writing a DSL for expressing flow (original I know) in groovy. I would like to provide the user the ability to write functions that are stored and evaluated at certain points in the flow. Something like:

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

Now, I am pretty sure I could surround the closure in quotes and store that. But I would like to keep syntax highlighting and content assist if possible when editing these DSLs. I realize that the closure COULD reference artifacts from the surrounding flow definition which would no longer be valid when executing the closure in a different context, and I am fine with this. In reality I would like to use the closure syntax for a non-closure function definition.

tl;dr; I need to get the closure's code while evaluating the DSL so that it can be stored in the database and executed by a script host later.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

微暖i 2024-12-28 04:21:57

我认为没有办法获取闭包的源代码,因为这些信息在编译过程中被丢弃。也许你可以尝试编写一个 AST 转换 来制作闭包的语法树在运行时可用。

如果您只关心将闭包存储在数据库中,并且以后不需要访问源代码,则可以尝试将其序列化并存储序列化形式。

Closure 实现了 Serialized,并在将其 ownerthisObjectdelegate 属性清空后,我能够序列化它,但我在反序列化时收到 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

经过一番搜索,我发现了Groovy Remote Control,这是一个专门为实现序列化闭包和执行而创建的库稍后,可能在远程计算机上。尝试一下,也许这就是您所需要的。

I don't think there is a way to get a closure's source code, as this information is discarded during compilation. Perhaps you could try writing an AST transformation that would make closure's syntax tree available at runtime.

If all you care about is storing the closure in the database, and you don't need later access to the source code, you can try serializing it and storing the serialized form.

Closure implements Serializable, and after nulling its owner, thisObject and delegate attributes I was able to serialize it, but I'm getting ClassNotFoundException on deserialization.

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

After some searching, I found Groovy Remote Control, a library created specifically to enable serializing closures and executing them later, possibly on a remote machine. Give it a try, maybe that's what you need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文