gpt4 book ai didi

java - 我如何说服 GroovyShell 通过 eval() 调用维护状态?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:05:11 25 4
gpt4 key购买 nike

我正在尝试使用 Groovy 为我的应用程序创建交互式脚本/宏模式。该应用程序是 OSGi,脚本可能需要的大部分信息事先并不知道。我想我可以使用 GroovyShell 并多次调用 eval() 以在加载 OSGi 包时不断附加到命名空间。 GroovyShell 通过多个 eval 调用维护变量状态,但不维护类定义或方法。

目标:在启动时创建一个基类。随着 OSGi 包的加载,根据需要创建派生类。

最佳答案

我不确定你所说的声明的类在评估之间不存在是什么意思,以下两个脚本在一个接一个评估时按预期工作:

class C {{println 'hi'}}
new C()

...

new C()

然而,方法会绑定(bind)到声明它们的类,并且 GroovyShell 会为每个实例创建一个新类。如果您不需要任何脚本的返回值并且它们是真正的脚本(不是具有主要方法的类),您可以将以下内容附加到每个评估脚本的末尾。

Class klass = this.getClass()
this.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
binding[it.name] = this.&"$it.name"
}
}

如果您依赖于返回值,您可以手动管理评估并在解析过程中运行脚本(警告,以下是未经测试的代码,仅供说明用途)...

String scriptText = ...
Script script = shell.parse(scriptText)
def returnValue = script.run()
Class klass = script.getClass()
script.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
shell.context[it.name] = this.&"$it.name"
}
}
// do whatever with returnValue...

我相信您知道最后一个警告。静态类型变量不会保留在 eval 之间,因为它们没有存储在绑定(bind)中。所以在前面的脚本中,变量“klass”不会在脚本调用之间保留,并且会消失。要纠正这一点,只需删除第一次使用所有变量时的类型声明,这意味着它们将被读取并写入绑定(bind)。

关于java - 我如何说服 GroovyShell 通过 eval() 调用维护状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45582/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com