为什么我不能通过 Perl 通过 JSON::XS 正确编码来自 PostgreSQL 的布尔值?

发布于 2024-07-27 01:32:40 字数 1668 浏览 8 评论 0原文

我对 PostgreSQL 系统有一个返回布尔值的查询:

my $sth = $dbh->prepare("select 'f'::boolean");
$sth->execute;
my @vals = $sth->fetchrow_array;

根据 DBD::Pg文档

目前的实施 PostgreSQL 返回“t”表示 true 和 “f”代表假。 从 Perl 的角度来看 看来,这是一个相当不幸的 选择。 DBD::Pg 因此翻译为 a 中 BOOL 数据类型的结果 Perlish 方式:“f”成为数字 0 和 't' 变成数字 1。这 应用程序不必这样做 检查返回的特定数据库 数据类型 BOOL 的值,因为 Perl 将 0 视为 false,将 1 视为 true。 您可以设置 pg_bool_tf 属性 为真实值以更改值 如果您愿意,可以返回“t”和“f”。

因此,只要 pg_bool_tf 返回 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);

...dies with:

{"layout":0,"show_widget_help":"0"}

...这将是很好,只是我的 JavaScript 期望那里有一个布尔值,并且非空字符串“0”被评估为 true。 为什么后面的0被引用而前者没有?

根据 JSON::XS 文档,这是一个主要功能:

往返完整性

当您序列化 Perl 数据时 仅使用数据类型的结构 由 JSON 支持,反序列化 数据结构是相同的 Perl 级别。 (例如字符串“2.0” 不会突然变成“2” 因为它看起来像一个数字)。 那里 少数情况除外,请阅读 下面的 MAPPING 部分可了解 那些。

...其中说:

简单 Perl 标量(任何标量 不是参考)是最 难以编码的对象:JSON::XS 将未定义的标量编码为 JSON 空值,最后的标量 之前曾在字符串上下文中使用过 编码为 JSON 字符串以及任何内容 否则为数值。

但我从不在字符串上下文中使用@vals[0]。 也许 DBD::Pg 在返回之前在某处使用其布尔值 0 作为字符串?

I have a query on a PostgreSQL system returning a boolean:

my $sth = $dbh->prepare("select 'f'::boolean");
$sth->execute;
my @vals = $sth->fetchrow_array;

According to the DBD::Pg docs,

The current implementation of
PostgreSQL returns 't' for true and
'f' for false. From the Perl point of
view, this is a rather unfortunate
choice. DBD::Pg therefore translates
the result for the BOOL data type in a
Perlish manner: 'f' becomes the number
0 and 't' becomes the number 1. This
way the application does not have to
check the database-specific returned
values for the data-type BOOL because
Perl treats 0 as false and 1 as true.
You may set the pg_bool_tf attribute
to a true value to change the values
back to 't' and 'f' if you wish.

So, that statement should return a 0, which it does, so long as pg_bool_tf returns 0, which it does. However, somewhere along the way JSON::XS (and plain JSON) interprets the returned 0 as a string:

use JSON::XS qw(encode_json);
my $options =
{
    layout => 0,
    show_widget_help => $vals[0] // 1,
};
die encode_json($options);

...dies with:

{"layout":0,"show_widget_help":"0"}

...which would be fine, except that my JavaScript is expecting a boolean there, and the non-empty string "0" gets evaluated to true. Why is the latter 0 quoted and the former not?

According to the JSON::XS docs, this is a main feature:

round-trip integrity

When you serialise a perl data
structure using only data types
supported by JSON, the deserialised
data structure is identical on the
Perl level. (e.g. the string "2.0"
doesn't suddenly become "2" just
because it looks like a number). There
minor are exceptions to this, read the
MAPPING section below to learn about
those.

...which says:

Simple Perl scalars (any scalar that
is not a reference) are the most
difficult objects to encode: JSON::XS
will encode undefined scalars as JSON
null values, scalars that have last
been used in a string context before
encoding as JSON strings, and anything
else as number value.

But I never use @vals[0] in a string context. Maybe DBD::Pg uses its boolean 0 as a string somewhere before returning it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪落纷纷 2024-08-03 01:32:40

JSON::XS 文档表示以下内容将转换为

  • 对整数 0true/false 的引用1,即。 \0\1
  • JSON::XS::trueJSON::XS::false

使用一个这些应该可以解决你的问题

The JSON::XS doc says the following will be converted to true/false

  • references to the integers 0 and 1, ie. \0 and \1
  • JSON::XS::true and JSON::XS::false

Using one of these should solve your problem

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文