由Eval或GroovyShell执行时的惰性GString评估

时间:2014-06-23 17:13:23

标签: groovy eval lazy-evaluation groovyshell

对于监控系统,我需要评估由布尔表达式表示的自定义检查。例如,我有一个简单的伪代码条件(它们可能更复杂):

if (webservice is unavailable) and (there are no emails about planned downtime)

如果可能的话,我想在这里使用short-circuit evaluation,这样如果网络服务可用(并且第一个条件是false),第二部分就不会被评估,总的来说,无论如何都是false。因此,我可以避免在没必要时连接到邮件服务器(以及其他耗时的操作)。

以下是我试图实现的一个例子:

class WebserviceDownCheck {
  boolean check() { 
    println 'Checking webservice'
    return false 
  }
}

class NoDowntimeEmailCheck {
  boolean check() { //shouldn't be executed
    println 'Checking emails'
    return true 
  }
}
//using string evaluation, because conditions are constructed during runtime
Eval.me("${new WebserviceDownCheck().check()} && ${new NoDowntimeEmailCheck().check()}")

输出结果为:

Checking webservice
Checking emails //shouldn't be there
Result: false

NoDowntimeEmailCheck().check()不应该被执行,因为第一个条件已经是false。 我试过了:

  • 使用GroovyShell代替Eval
  • check()方法更改为字段并应用@Lazy转换
  • ${new WebserviceDownCheck().check()}更改为${ -> new WebserviceDownCheck().check()}(看到here

似乎我需要一些惰性机制,这将允许我在GString(或Eval)已经执行它时初始化GroovyShell。对Binding来说可能是懒惰的GroovyShell

我想知道,如果不编写自定义字符串评估逻辑,它是否可行?

1 个答案:

答案 0 :(得分:3)

将它合并为一个表达式,如下所示:

Eval.me("${new WebserviceDownCheck().check() && new NoDowntimeEmailCheck().check()}")

如果结果为false,则仅评估第一个。