流口水布尔比较

时间:2018-12-31 16:31:25

标签: drools

为什么false == (cancelationCode == 'C')的行为不同
来自(cancelationCode == 'C') == false

是Drools 6.5.0中的bug还是我缺少任何东西?


这里是全文:

我正在使用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语句,并具有否定它们的能力。

最初,NOT未实现为!,并且适用于当前情况。但这不适用于buySellTypeCode in ('B', 'S')之类的情况,尽管这种情况正在与false == statement一起工作。

当DSL评估为

时,不会为输入对象触发规则。
$trade: Trade((recordTypeCode == '910') && false == (cancellationCode == 'C'))    

,当DSL评估为

时,它将为同一输入对象触发
$trade: Trade((recordTypeCode == '910') && (cancellationCode == 'C') == false)

1 个答案:

答案 0 :(得分:0)

由于使用DRL6词法分析器进行了不同的解析,因此它的行为确实有所不同。
org.drools.compiler.compiler.DrlExprParser.parse照原样使用这些文本片段,但
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

我会说这种“优化”是一个错误。