【问题标题】:Drools boolean comparisonDrools 布尔比较
【发布时间】: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' 意味着对于同一个输入对象,一个语句触发规则,而另一个语句不触发

标签: drools


【解决方案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

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

【讨论】:

    猜你喜欢
    • 2012-08-19
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多