Drools 布尔比较
Posted
技术标签:
【中文标题】Drools 布尔比较【英文标题】:Drools boolean comparison 【发布时间】:2019-05-28 02:35:29 【问题描述】:为什么false == (cancelationCode == 'C')
bahave 不同
来自(cancelationCode == 'C') == false
?
是drools 6.5.0 中的错误还是我遗漏了什么?
这里是完整的故事:
我正在使用 Drools DSL,我必须实现一个规则:
rule "my business rule"
dialect "mvel"
when
There is a trade that
- Supervised Trade
...
then
...
end
我有这些 DSL 定义:
[when] Supervised Trade =
Customer Trade
AND NOT Canceled
[when] Customer Trade = (recordTypeCode is equal to '910')
[when] Canceled = (cancellationCode is equal to 'C')
[when] is equal to = ==
[when] var1?(?<![\w'])\s*AND\s*(?![\w'])var2? = var1 && var2
[when] var1?(?<![\w'])\s*OR\s*(?![\w'])var2? = var1 || var2
[when] var1?(?<![\w'])\s*NOT\s*(?![\w'])var2? = var1 false == var2
要求是以积极的方式编写可重用的DSL语句并具有否定它们的能力。
最初不是作为!
实现的,它适用于当前场景。但它不适用于buySellTypeCode in ('B', 'S')
之类的情况,但它适用于false == statement
。
当 DSL 被评估为输入对象时,规则不会被触发
$trade: Trade((recordTypeCode == '910') && false == (cancellationCode == 'C'))
当 DSL 被评估为相同的输入对象时触发
$trade: Trade((recordTypeCode == '910') && (cancellationCode == 'C') == false)
【问题讨论】:
可能是因为第一个cancelationCode
有一个 L,而第二个有两个?
不,只是我的错字,我在这里放了简化的表达方式来展开讨论)
您必须展示一个完整的示例 (minimal reproducible example) 来演示该问题,并解释“bahaves different”的含义。 cancelationCode
的值是多少?这些比较的结果是什么?问题很可能出在代码的其他地方。
抱歉,我在想它的 ='C'。
'behaves different' 意味着对于同一个输入对象,一个语句触发规则,而另一个语句不触发
【参考方案1】:
它的行为确实不同,因为它使用 DRL6 词法分析器的解析方式不同。org.drools.compiler.compiler.DrlExprParser.parse
按原样处理这些文本 sn-ps,但BaseDescr expr = parser.conditionalOrExpression();
表明 ANTLR 解析器处理这些文本的方式不同。
当我将false == (cancelationCode == 'C')
更改为true ^ (cancelationCode == 'C')
时出现错误:“谓词'true ^ cancelCode =='C'' 必须是布尔表达式”。这揭示了问题的根本原因 - ANTLR 解析器在单个语句周围去掉大括号,这就是为什么
false == cancelationCode == 'C' -> doesn't work as expected
cancelationCode == 'C' == false -> works as expected
有趣的是,复杂的语句并没有去掉大括号,所以两者都按预期工作:
false == (true && cancelationCode == 'C')
(true && cancelationCode == 'C') == false
我会说这种“优化”是一个错误。
【讨论】:
以上是关于Drools 布尔比较的主要内容,如果未能解决你的问题,请参考以下文章