17 January 2016

表达式引擎把一段条件文本变成计算结果。阅读 Nutz 的 EL 模块时,可以沿“识别符号、处理优先级、执行运算”这条线理解,而不是只记住几个包名。下面以 1.b.53 为例。

从一个告警条件开始

import org.nutz.el.El;
import org.nutz.lang.Lang;
import org.nutz.lang.util.Context;

Context values = Lang.context();
values.set("a", 85);
values.set("b", 20);
Object result = El.eval(values, "a > 80 && a - b > 50");

这是调用片段,result 应按规则的预期类型检查,而不是无条件转为 Boolean。相同文本在缺失变量、不同数值类型下的行为,也需要明确。

优先级怎样进入计算

org.nutz.el.parse 处理表达式中的记号,obj 表示操作对象,opt 表示运算。在 arithmetic 包中,ShuntingYard 与 RPN 对应中缀表达式处理和逆波兰形式的求值思路。

例如 1 + 2 * 3 不能简单从左到右计算。优先级处理决定先乘后加;括号则改变组合顺序。阅读时先跟进不含变量的小表达式,再加入上下文变量和比较运算,会更容易定位转换与求值的分界。

可配置规则需要独立验证

除零、空值、整数精度和返回类型,都是规则系统需要约定的行为。规则返回 false 与执行异常分开记录,并保存规则版本和样例输入,才能解释一次判断。

表达式允许调用哪些能力,应由应用和对应版本实现明确限制,不能因为它叫 EL 就认为天然隔离了文件、网络或任意方法调用。对外开放前限制输入来源、长度与执行资源,可信规则也先测试后启用。

参考:Nutz 1.b.53 源码。





blog comments powered by Disqus
Fork me on GitHub