Search code examples
jsonruby

Parsing JSON without any conversions in Ruby


I am writing a Ruby script to migrate JSON files from one format to another. In this, I need to preserve the exact contents and formatting of all the values. Is there a JSON library in Ruby that will parse a file without any value validation or conversion, just leaving them as strings?

The default JSON library converts all numbers to Float, often losing precision. OJ can parse to BigDecimal, but then prints all the numbers in scientific notation. Neither lets me just skip conversion altogether.


Solution

  • If you're just concerned with parsing decimal numbers, there is a decimal_class option. You could use this to choose a different class like BigDecimal or to provide your own parser:

    string = "{\"num\":222.95816040039063}"
    
    JSON.parse(string)
     => {"num"=>222.95816040039062}
    
    JSON.parse(string, decimal_class: BigDecimal)
     => {"num"=>0.22295816040039063e3}
    
    class NoConversion
      def initialize(raw)
        @raw = raw
      end
    end
    JSON.parse(string, decimal_class: NoConversion)
     => {"num"=>#<NoConversion:0x0000000110509a90 @raw="222.95816040039063">}
    

    And as @Stefan has pointed out, you can define a to_json method to generate JSON from the custom decimal class:

    class NoConversion
      def initialize(raw)
        @raw = raw
      end
    
      def to_json(*)
        @raw
      end
    end
    
    hash = JSON.parse(string, decimal_class: NoConversion)
     => {"num"=>#<NoConversion:0x0000000110511fd8 @raw="222.95816040039063">}
    
    JSON.generate(hash)
     => "{\"num\":222.95816040039063}"