gpt4 book ai didi

ruby - Perl 和 Ruby 之间的 YAML 数据交换问题

转载 作者:数据小太阳 更新时间:2023-10-29 07:07:52 25 4
gpt4 key购买 nike

我在通过 YAML 在 Perl 和 Ruby 之间交换数据时遇到问题。我有一些看起来像数字:数字的值,例如 1:16

Perl 的 YAML 库(Tiny 和 XS)将其编码为 1:16,不带引号。 Ruby 的 YAML 库 (Psych) 不会将其解释为字符串,而是以某种方式变成 Fixnum 值 4560。我不知道如何在任何一方解决这个转换问题。

我用例的 YAML 中的每个值都应该是一个对象或字符串。因此,如果存在这样的选项,我可以告诉 Perl YAML 库引用所有值。或者有什么方法可以告诉 Ruby YAML 库将所有​​值解释为字符串?有任何想法吗?

从逻辑上讲,改变任何一方的语言都不是一种选择。

Perl:

use YAML::XS qw(DumpFile);
my $foo={'abc'=>'1:16'};
DumpFile('test.yaml',$foo);

ruby :

require('yaml')
foo=YAML.load_file('test.yaml')
puts(foo['abc'])

Ruby 代码将打印 4560。其中一条评论说明了如何从 1:16 得到 4560,即 1 小时 16 分钟转换为秒。嗯,好的。

最佳答案

根据Yaml 1.1 spec , 1:16 是一个六十进制(以 60 为底)格式的整数。

另见 http://yaml.org/type/int.html ,它说:

Using “:” allows expressing integers in base 60, which is convenient for time and angle values.

Ruby、Psych 中包含的 Yaml 解析器,recognises this format and converts the value into an integer (错误地,1:16 应该是 71——Psych 代码似乎假设所有这些值都将采用 a:b:c 的形式,但正则表达式并不强制执行)。 Perl 发射器(至少我测试过的 YAML::XS)不识别这种格式,所以在写入文件时不引用字符串。 YAML::XS 确实识别并引用了一些整数,但不是全部。 YAML::XS 也无法识别 Psych 可以识别的许多其他格式(例如日期)。

(好像是六十进制格式has been removed from the Yaml 1.2 spec。)

Psych 在其解析中提供了相当大的灵 active ——YAML.load_file 只是常见用例的简单接口(interface)。

您可以使用 Psych 的 parse 方法创建 yaml 的树表示,然后使用自定义 ScalarScanner(这是将特定格式的字符串转换为适当的 Ruby 类型的对象):

require('yaml')

class MyScalarScanner < Psych::ScalarScanner
def tokenize string
#this is the same regexp as Psych uses to detect base 60 ints:
return string if string =~ /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
super
end
end

tree = YAML::parse_file 'test.yaml'
foo = Psych::Visitors::ToRuby.new(MyScalarScanner.new).accept tree

这与使用 YAML.load_file 时发生的过程基本相同,只是它使用了自定义的扫描器类。

类似的替代方法是打开 ScalarScanner 并将 tokenize 方法替换为自定义方法。这将允许您使用更简单的 load_file 接口(interface),但带有关于猴子修补类的常见警告:

class Psych::ScalarScanner
alias :orig_tokenize :tokenize
def tokenize string
return string if string =~ /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
orig_tokenize string
end
end

foo = YAML.load_file 'test.yaml'

请注意,这些示例仅考虑格式为 1:16 的值。根据您的 Perl 程序发出的内容,您可能还需要覆盖其他模式。您可能特别想看看的一个是六十进制 float (例如 1:16.44)。

关于ruby - Perl 和 Ruby 之间的 YAML 数据交换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12610187/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com