Drools 布尔值比较
Drools boolean comparison
为什么 false == (cancelationCode == 'C')
行为不同
来自 (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 语句,并有能力否定它们。
最初 NOT 是作为 !
实现的,它适用于当前场景。但它不适用于像 buySellTypeCode in ('B', 'S')
这样的情况,尽管它与 false == statement
一起工作。
当 DSL 被评估为
时,不会为输入对象触发规则
$trade: Trade((recordTypeCode == '910') && false == (cancellationCode == 'C'))
并且当 DSL 被评估为
时,为同一输入对象触发
$trade: Trade((recordTypeCode == '910') && (cancellationCode == 'C') == false)
它的行为确实不同,因为它使用 DRL6 词法分析器进行了不同的解析。
org.drools.compiler.compiler.DrlExprParser.parse
按原样使用这些文本片段,但是
BaseDescr expr = parser.conditionalOrExpression();
表明 ANTLR 解析器以不同的方式处理这些。
当我将 false == (cancelationCode == 'C')
更改为 true ^ (cancelationCode == 'C')
时,出现错误:"Predicate 'true ^ cancellationCode == 'C'' must be a Boolean expression"。这揭示了问题的根本原因——ANTLR 解析器去掉了单个语句周围的大括号,这就是为什么
false == cancelationCode == 'C' -> doesn't work as expected
cancelationCode == 'C' == false -> works as expected
有趣的是,复杂语句周围的大括号并没有被剥离,因此两者都按预期工作:
false == (true && cancelationCode == 'C')
(true && cancelationCode == 'C') == false
我会说这 'optimization' 是一个错误。
为什么 false == (cancelationCode == 'C')
行为不同
来自 (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 语句,并有能力否定它们。
最初 NOT 是作为 !
实现的,它适用于当前场景。但它不适用于像 buySellTypeCode in ('B', 'S')
这样的情况,尽管它与 false == statement
一起工作。
当 DSL 被评估为
时,不会为输入对象触发规则$trade: Trade((recordTypeCode == '910') && false == (cancellationCode == 'C'))
并且当 DSL 被评估为
时,为同一输入对象触发$trade: Trade((recordTypeCode == '910') && (cancellationCode == 'C') == false)
它的行为确实不同,因为它使用 DRL6 词法分析器进行了不同的解析。
org.drools.compiler.compiler.DrlExprParser.parse
按原样使用这些文本片段,但是
BaseDescr expr = parser.conditionalOrExpression();
表明 ANTLR 解析器以不同的方式处理这些。
当我将 false == (cancelationCode == 'C')
更改为 true ^ (cancelationCode == 'C')
时,出现错误:"Predicate 'true ^ cancellationCode == 'C'' must be a Boolean expression"。这揭示了问题的根本原因——ANTLR 解析器去掉了单个语句周围的大括号,这就是为什么
false == cancelationCode == 'C' -> doesn't work as expected
cancelationCode == 'C' == false -> works as expected
有趣的是,复杂语句周围的大括号并没有被剥离,因此两者都按预期工作:
false == (true && cancelationCode == 'C')
(true && cancelationCode == 'C') == false
我会说这 'optimization' 是一个错误。