JQ 1.6版本update operator更新对象返回空对象或错误结果问题咨询
问题根因
这是jq 1.6版本中|=更新运算符的已知上下文绑定bug:当|=右侧表达式直接调用包含错误捕获逻辑(?后缀、try catch)的函数时,会破坏.的原有绑定关系。
正常情况下path |= expr的执行逻辑是:提取path对应的值作为.传入右侧expr计算,再将计算结果写回原路径,同时保留输入对象的其余字段。但在1.6版本中,右侧的错误捕获逻辑会打乱该流程:
- 示例1正常的原因:你在进入
|=逻辑前就已经把numberify的计算结果存入了$intValue变量,|=右侧没有直接调用带错误捕获的函数,所以.绑定正常,可以正确取到.a的值进行计算。 - 示例2返回空对象的原因:
tonumber? // 0的?错误捕获触发了bug,直接清空了|=右侧的.上下文,导致整个右侧表达式返回空值,最终.a字段被赋值为空,整个对象输出为{}。 - 示例3结果不符合预期的原因:
try tonumber catch 0的错误捕获逻辑没有完全清空上下文,但错误地将.绑定到了顶层输入对象,而非.a对应的子对象,所以.b取值为null,相加时null会被默认为0,最终得到错误的计算结果。
方案说明
你使用的两种规避方案都可以避开该bug:
- 提前将函数计算结果存入变量再传入
|=右侧:避免了在|=作用域内直接调用带错误捕获的函数,不会触发上下文绑定异常。 - 改用
+=运算符:+=是专门的增量更新运算符,内部实现逻辑和|=不同,不会触发该bug,代码也更简洁易读。
该bug在jq 1.7及以上版本已经被修复,如果你可以升级jq版本,升级后示例2、3的原始写法也可以正常运行。
内容的提问来源于stack exchange,提问作者jpseng
相关产品推荐
相关产品推荐

