我在返回布尔值的 PostgreSQL 系统上有一个查询:
my $sth = $dbh->prepare("select 'f'::boolean");
$sth->execute;
my @vals = $sth->fetchrow_array;
根据DBD::Pg 文档,
PostgreSQL 的当前实现返回 't' 为真,'f' 为假。从 Perl 的角度来看,这是一个相当不幸的选择。因此,DBD::Pg 以 Perlish 方式转换 BOOL 数据类型的结果:“f”变成数字 0,“t”变成数字 1。这样应用程序就不必检查特定于数据库的返回值BOOL 数据类型,因为 Perl 将 0 视为假,将 1 视为真。如果您愿意,您可以将 pg_bool_tf 属性设置为真值以将值更改回“t”和“f”。
因此,只要 pg_bool_tf 返回 0,它就会返回 0,它会返回 0。然而,在 JSON::XS(和纯 JSON)的某个地方,将返回的 0 解释为字符串:
use JSON::XS qw(encode_json);
my $options =
{
layout => 0,
show_widget_help => $vals[0] // 1,
};
die encode_json($options);
...死于:
{"layout":0,"show_widget_help":"0"}
...这很好,除了我的 JavaScript 期望那里有一个布尔值,并且非空字符串“0”被评估为真。为什么后面的 0 被引用而前者不被引用?
根据JSON::XS docs,这是一个主要功能:
往返完整性
当您仅使用 JSON 支持的数据类型序列化 perl 数据结构时,反序列化的数据结构在 Perl 级别上是相同的。(例如字符串“2.0”不会因为它看起来像一个数字而突然变成“2”)。有一些例外情况,请阅读下面的映射部分以了解这些情况。
...它说:
简单的 Perl 标量(任何不是引用的标量)是最难编码的对象:JSON::XS 会将未定义的标量编码为 JSON 空值、在编码为 JSON 字符串之前最后在字符串上下文中使用的标量,以及其他任何数值。
但我从不在字符串上下文中使用@vals[0]。也许 DBD::Pg 在返回它之前使用它的布尔值 0 作为字符串?