YAML:挪威问题(The Norway Problem)

1,016 阅读2分钟

根据 iso-3166-country-codes 标准每个国家都有自己的代码,作为唯一标识,可以被拿来做很多事情,比如互联网域名系统使用这些代码来定义顶级域名,例如 cn 中国,.fr 代表法国,.au 代表澳大利亚等等。

这些国家代码是来源于 iso-3166-country-codes 标准,之所以是两个字母组合那是因为它符合 alpha-2,还有三个字母(alpha-3),四个字母(alpha-4)。

好了,现在我们用两个字母组合的国家代码,通过创建一个 YAML 配置文件开始使网站国际化。我们首先添加英国、爱尔兰、法国和德国。”

countries:
- GB
- IE
- FR
- DE

上面的 YAML 用 Online YAML Parser 工具编译成 JSON 如下:

https://yaml-online-parser.appspot.com/

看起来毫无问题,当我们继续添加国家代码时,比如 NO —— Norway(挪威),继续编译成 JSON。

https://yaml-online-parser.appspot.com/

NO 编译成了 false,这就是 YAML 中一个很常见的——挪威问题🇳🇴。

在 YAML 中什么值能合法的编译成布尔值呢?根据 YAML 的文档:

yaml.org/type/bool.h…

我们得到如下非常复杂的规则:

 y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

现在我们知道了原来是 NO 错误触发 YAML 的布尔转换。

如何避免,答案就是给 NO 加上引号变成 "NO" 或 'NO',:

countries:
- GB
- IE
- FR
- DE
- 'NO'

再次看编译结果:

事实上我们在写 YAML 的时候很少会对字符串加上引号,YAML 的宽松规则就会对编译造成影响,再比如有个记者的名字叫做Christopher Null,我们在用 YAML 存储他的名字:

first name: Christopher
surname: Null

结果就很严重,本来 surname 是 'null' 字符串,YAML 直接编译成了空值 null。

从这个角度上讲,YAML 不仅是不方便的还是复杂的,以后更加坚定是 JSON 的捍卫者。

参考