51

在过去 6 个月左右的时间里,我一直在使用 YAML 格式并取得了相当大的成功。

然而,YAML 解析器的纯 Perl 实现对于手动编写可读文件相当烦躁,并且(在我看来)有烦人的怪癖,例如需要在文件末尾换行。与我的程序的其余部分相比,它也非常慢。

我正在考虑我的项目的下一步发展,我正在考虑改用 JSON(事实证明,这是 YAML 的一个严格的子集)。但是哪种格式在 Perl 中具有最大的社区吸引力和努力?

今天,对于 Perl、YAML 或 JSON 中的简单数据描述来说,哪种格式似乎是更好的长期格式,为什么?

4

7 回答 7

84

YAML 与 JSON 在 Perl 中还没有解决,我承认我倾向于在这中间。我的建议是,两者都会让你获得尽可能多的社区牵引力。我会根据格式的各种利弊做出决定。我分解了各种数据序列化选项,如下所示(我将访问社区 wiki,以便人们可以添加):

YAML 优点

  • 人性化,人们在不知不觉中编写基本的 YAML
  • 所见即所得的字符串
  • 富有表现力(具有 TMTOWDI 特性)
  • 可扩展类型/元数据系统
  • Perl 兼容的数据类型
  • 便携的
  • 熟悉(很多内联和字符串语法看起来像 Perl 代码)
  • 如果您有编译器(YAML::XS),则可以很好地实现
  • 良好的 Perl 数据转储能力
  • 紧凑地使用屏幕空间(可能,您可以格式化以适应一行)

YAML 缺点

  • 大规格
  • 不可靠/不完整的纯 Perl 实现
  • 空格作为语法可能会引起争议。

JSON 优点

  • 人类可读/可写
  • 小规格
  • 好的实现
  • 便携的
  • Perlish 语法
  • YAML 1.2 是 JSON 的超集
  • 屏幕空间的紧凑使用
  • Perl 友好的数据类型
  • 很多东西都处理 JSON

JSON 缺点

  • 字符串不是所见即所得
  • 没有可扩展性
  • 一些 Perl 结构必须以特殊方式表达(对象和球体)
  • 缺乏表达性

XML 优点

  • 广泛使用
  • Web 开发人员熟悉的语法
  • 大量优秀 XML 模块的语料库
  • 模式
  • 搜索和转换数据的技术
  • 便携的

XML 缺点

  • 人类阅读和写作很乏味
  • Perl 以外的数据结构
  • 缺乏表达性
  • 大规格
  • 详细

Perl/Data::Dumper 优点

  • 无依赖
  • 出人意料的紧凑(带有正确的标志)
  • Perl 友好
  • 几乎可以转储任何东西(通过DDS
  • 富有表现力
  • 屏幕空间的紧凑使用
  • 所见即所得的字符串
  • 熟悉的

Perl/Data::Dumper 缺点

  • 不可移植(到其他语言)
  • 不安全(没有英勇的措施)
  • 非 Perl 程序员难以理解

可存储的优点

  • 袖珍的?(没有数字来支持它)
  • 快速地?(没有数字来支持它)

可存储的缺点

  • 人类敌对
  • 跨可存储版本不兼容
  • 不可移植(到其他语言)
于 2009-12-09T23:28:20.710 回答
13

与大多数事情一样,这取决于. 我认为如果您想要速度和互操作性(与其他语言),请使用 JSON,特别是JSON::XS

如果你想要一些只能被 Perl 模块使用的东西,请坚持使用 YAML。在 CPAN 上找到支持使用 YAML 进行数据描述或依赖于 YAML 的 Perl 模块比 JSON 更常见。

请注意,我不是权威,这种观点主要基于预感和猜想。特别是,我没有分析 JSON::XS 与YAML::XS。如果我无知得冒犯,我只能希望我能通过纠正我让某人愤怒到为讨论带来有用的信息。

于 2009-12-09T20:54:45.543 回答
11

一切都与人类可读性有关,如果这是您的主要关注点,请选择 YAML:

YAML:

american:
  - Boston Red Sox
  - Detroit Tigers
  - New York Yankees
national:
  - New York Mets
  - Chicago Cubs
  - Atlanta Braves

JSON:

{
  "american": [
    "Boston Red Sox", 
    "Detroit Tigers", 
    "New York Yankees"
  ], 
  "national": [
    "New York Mets", 
    "Chicago Cubs", 
    "Atlanta Braves"
  ]
}
于 2012-12-19T11:49:28.613 回答
4

纯 Perl YAML 实现(YAML相对于模块YAML::Syck)似乎有一些严重的问题。我最近遇到了无法处理行很长(大约 32k 个字符)的 YAML 文档的问题。

YAML 能够存储和加载祝福变量,并且默认情况下这样做(下面的代码片段是从*sepia-repl*Emacs 中的缓冲区复制的):

I need user feedback!  Please send questions or comments to seano@cpan.org.
Sepia version 0.98.
Type ",h" for help, or ",q" to quit.
main @> use YAML
undef
main @> $foo = bless {}, 'asdf'
bless( {}, 'asdf' )
main @> $foo_dump = YAML::Dump $foo
'--- !!perl/hash:asdf {}
'
main @> YAML::Load $foo_dump
bless( {}, 'asdf' )

这在安全方面是相当可怕的,因为不受信任的数据可用于调用DESTROY已在您的应用程序中定义的任何方法——或它使用的任何模块。

下面的简短程序演示了这个问题:

#!/usr/bin/perl
use YAML;
use Data::Dumper;
package My::Namespace;
sub DESTROY {
    print Data::Dumper::Dumper \@_;
}
package main;
my $var = YAML::Load '--- !!perl/hash:My::Namespace
bar: 2
foo: 1
';

默认情况下 JSON 不允许这样做——可以序列化 Perl“对象”,但为了做到这一点,您必须定义 TO_JSON 方法。

于 2009-12-10T14:46:28.360 回答
1

如果您正在考虑 JavaScript 对象表示法,为什么不使用“Perl 对象表示法”?

JSON:

{"name": "bob", "parents": {"mother": "susan", "father": "bill"}, "nums": [1, 2, 3]}

珀尔:

{name => "bob", parents => {mother => "susan", father => "bill"}, nums => [1, 2, 3]}
于 2009-12-10T02:56:23.703 回答
1

我使用 YAML 来跟踪进程的状态,因为我可以在进程中间读取 YML。您(技术上)需要完整格式的文档来读取 XML 或 JS。YAML 非常适合跟踪状态,因为您可以将大量迷你文档写入文件。否则,我通常使用 XML 或 JS。顺便说一句,上面的优缺点很好的总结。

于 2014-09-16T16:00:47.467 回答
0

您可能还想考虑使用Storable。你可能会得到一个非常好的速度提升。权衡是:

  • 可存储格式是二进制的,不像 JSON 或 YAML 那样人类可读
  • Storable 不是纯粹的 Perl 模块(如果重要的话)
于 2009-12-09T21:12:47.910 回答