【问题标题】:Force YAML::Tiny values to be numbers强制 YAML::Tiny 值是数字
【发布时间】:2017-12-20 13:25:54
【问题描述】:

假设我有以下 YAML 文件:

---
task:
  1:
    command: '<task1_command>'
    desc: '<task1_description>'
  2:
    command: '<task2_command>'
    desc: '<task2_description>'

我使用 Perl 和 YAML::Tiny 读取文件:

$TASKS = YAML::Tiny->read(<YAML_file>);

而且我可以正常使用 desc/command 值,但如果我使用以下方式编写 TASKS 数据:

$TASKS->write(<YAML_file>);

我得到了以下信息:

---
task:
  '1':
    command: '<task1_command>'
    desc: '<task1_description>'
  '2':
    command: '<task2_command>'
    desc: '<task2_description>'

任务编号在单引号之间!有没有办法“强制” YAML::Tiny 将任务值视为“数字”而不是“字符串”?

【问题讨论】:

    标签: perl yaml


    【解决方案1】:

    似乎没有办法解决这个问题,看起来这里已经提交了一个错误 ---

    YAML::Tiny

    不过,这可以使用 YAML 来完成,如下所示:

    #!/usr/bin/perl
    
    use warnings;
    use strict;
    use YAML;
    
    {
        no warnings;
        local $YAML::Numify = 1;
    }
    
    my $file = YAML::LoadFile('test.yml');
    
    open my $fh, '>', 'output.yml';
    print $fh YAML::Dump $file;
    close($fh);
    
    • 使用警告会产生一条消息,将本地 YAML::Numify 包裹起来是没有警告的花括号会抑制这一点。无论哪种方式,输出确实符合预期

    test.yml

    ---
    task:
      '1':
        desc: '85'
        command: '<task1_command>'
      2:
        desc: '100'
        command: '<task2_command>'
    

    output.yml

    ---
    task:
      1:
        command: '<task1_command>'
        desc: 85
      2:
        command: '<task2_command>'
        desc: 100
    

    【讨论】:

    • local $YAML::Numify = 1; 周围添加花括号而不移动任何其他内容完全消除了它的意义。一旦 Perl 遇到 }$YAML::Numify 将不再具有该值。如果这是您想要的,您将不得不在块内移动 LoadFile 调用。即使修正了这一点,::Numify 的值似乎也没什么区别。
    【解决方案2】:

    您数据中的12 在相应的Perl 数据结构中用作哈希键,因此必须始终是字符串。 read 调用的结果将是这样的

    bless([
      {
        task => {
          1 => { command => "<task1_command>", desc => "<task1_description>" },
          2 => { command => "<task2_command>", desc => "<task2_description>" },
        },
      },
    ], "YAML::Tiny")
    

    但是,如果您只是像使用数字一样使用数字字符串,Perl 总是会做正确的事情,所以我想知道您的应用程序需要这些值是“数字”是什么原因

    【讨论】:

    • 你说得对,应用程序的行为一切都很好......问题是应用程序可以更改某些任务值并且当它重新创建 YAML 文件时($TASKS->write()) 单引号不必要地添加到所有任务编号。
    • @Marcelo:这是接收程序的问题,还是你不喜欢它?
    • 这不是一个大问题(带引号的文件的工作方式相同)但有时人们在文件之间执行“差异”,并由于这些添加的引号而发现很多“差异”。
    • @Marcelo:那么我建议您应该将创建源 YAML 的任何内容更改为使用字符串,这样每个人都会很高兴。这个新的 YAML 数据的目标语言是什么?许多语言只允许字符串作为其类字典结构的键,并且像 Perl 一样,无法使用数字键生成 YAML。如果一切都失败了,那么您可以使用perl -i -pe 's/^\s*\K'(\d+)':/$1:/' myfile.yaml 对其进行后期处理,或者在diff 之前警告人们这可能是必要的。
    • @Marcelo:请注意,特别是,使用diff 比较两个 YAML 数据结构是一个非常糟糕的主意,因为相同的数据可能以许多不同的方式表示。最简单的例子是映射中键的顺序与语义无关,因此它们可以以任何顺序出现并保持等价。一个有用的替代方法是编写一个简单的 Perl 工具 yaml_diff,它使用 Data::Diff 来读取和比较两个 YAML 文件的内容。对我来说,这听起来是最好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-01-27
    • 2011-12-22
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 2021-06-15
    • 1970-01-01
    相关资源
    最近更新 更多