防止在Ruby中将字符串转换为八进制数

时间:2015-10-13 08:07:55

标签: ruby yaml

假设我们有以下ruby代码

require 'yaml'

h={"key"=>[{"step1"=>["0910","1223"]}]}
puts h.to_yaml

"0910"是一个字符串 但在to_yaml转换后,字符串变为八进制数。

---
key:
- step1:
  - 0910
  - '1223'

问题是我无法更改h变量。我从外面收到它,我需要在不改变的情况下解决问题。

4 个答案:

答案 0 :(得分:1)

根据YAML spec数字前缀为0信号和八进制基数(如Ruby中一样)。但是08不是有效的八进制数,所以它不会被引用。

当您从YAML文件加载此数据时,数据将完全按照您的需要显示。

0> h={"key"=>[{"step1"=>["0910","1223"]}]}
=> {"key"=>[{"step1"=>["0910", "1223"]}]}

0> yaml_h = h.to_yaml
=> "---\nkey:\n- step1:\n  - 0910\n  - '1223'\n"

0> YAML.load(yaml_h)
=> {"key"=>[{"step1"=>["0910", "1223"]}]}

如果您无法在此状态下使用数据,也许您可​​以扩展问题并提供更多详细信息。

答案 1 :(得分:1)

你错了YAML输出中有一个八进制数字。 YAML spec两次引用八进制,并且都清楚地表明YAML文件中的八进制数以0o开头(这类似于Ruby和更新版本的Python用于指定八进制; Python在版本3中也放弃了对0仅支持octals的支持,但Ruby似乎还没有这样做。

用于表示仅以0开头的八进制整数的自定义已被证明在许多语言中令人困惑,并且在六年前从YAML规范中删除。可能是您的解析器仍然支持它,但它不应该。

在任何情况下,字符89永远不会出现在表示为八进制数的整数中,因此在这种情况下,不会引起混淆,即该未引用的标量是一个数字。 字符串1223可以解释为普通整数,因此它必须始终表示为带引号的字符串标量。

有趣的是看看转储字符串"0708"时会发生什么。如果您的YAML库是最新的规范(版本1.2),它可以将其转储为不带引号的标量。由于o(或x)之后没有跟随前导零,因此可能没有混淆,这可能是八进制数(分别为十六进制),但是为了与旧解析器兼容(来自在2009之前)你的解析器可能只是引用它以保证安全。

答案 2 :(得分:0)

有类似的任务。 我在secrets.yml中使用:

processing_eth_address: "0x5774226def39e67d6afe6f735f9268d63db6031b"

OR

processing_eth_address: <%= "\'#{ENV["PROCESSING_ETH_ADDRESS"]}\'" %>

答案 3 :(得分:0)

我的 Ruby 没有进行这种八进制转换,但我遇到了类似的日期问题。我使用 to_yaml(canonical: true) 来解决这个问题。它更冗长,但它正确

{"date_of_birth" => "1991-02-29"}.to_yaml
=> "---\ndate_of_birth: 1991-02-29\n"
{"date_of_birth" => "1991-02-29"}.to_yaml(canonical: true)
=> "---\n{\n  ? \"date_of_birth\"\n  : \"1991-02-29\",\n}\n"