user3419308
user3419308

Reputation: 125

Preventing converting string into octal number in Ruby

Assume we have following ruby code

require 'yaml'

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

"0910" is a string but after to_yaml conversion, string turns into octal number.

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

the problem is I cannot change h variable. I receive it from outside, and I need to solve problem without changing it.

Upvotes: 5

Views: 2505

Answers (4)

Ponny
Ponny

Reputation: 702

My Ruby doesn't do this octal conversion but I had a similar issue with dates. I used to_yaml(canonical: true) to get around this issue. It's more verbose but it's correct.

{"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"

Upvotes: 0

artamonovdev
artamonovdev

Reputation: 2380

There was a similar task. I use in secrets.yml:

processing_eth_address: "0x5774226def39e67d6afe6f735f9268d63db6031b"

OR

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

Upvotes: 1

Anthon
Anthon

Reputation: 76682

You are mistaken that there is an octal number in your YAML output. The YAML spec refers to octal on two occasions, and both clearly indicate that an octal number in a YAML file starts with 0o (which is a similar to what Ruby and newer versions of Python use for specifying octal; Python also dropped the support for 0 only octals in version 3, Ruby doesn't seem to have done that—yet).

The custom to indicate octal integers starting with a 0 only, has been proven confusing in many language and was dropped from the YAML specification six years ago. It might be that your parser still supports it, but it shouldn't.

In any case the characters 8 and 9 can never occur in an integer represented as an octal number, so in this case there can be no confusion that that unquoted scalar is a number. The string 1223 could be interpreted as a normal integer, therefore it must always be represented as a quoted string scalar.

The interesting thing would be to see what happens when you dump the string "0708". If your YAML library is up-to-date with the spec (version 1.2) it can just dump this as an unquoted scalar. Because of the leading zero that is not followed by o (or x) there can be no confusion that this could be an octal number (resp. hexadecimal) either, but for compatibility with old parsers (from before 2009) your parser might just quote it to be on the safe side.

Upvotes: 4

RossMc
RossMc

Reputation: 426

According the the YAML spec numbers prefixed with a 0 signal an octal base (as does in Ruby). However 08 is not a valid octal number, so it doesn't get quoted.

When you come to load this data from the YAML file, the data appears exactly as you need.

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"]}]}

If you can't use the data in this state perhaps you could expand on the question and give more detail.

Upvotes: 1

Related Questions