Fork me on GitHub
Ruby 2.5 - Upcoming Dec 25th, 2017 - What's News?
Ruby 2.5.0 Changes
Official changes since the 2.4.0 release
Standard Gems 2.5.0 - Default Gems, Bundled Gems
by Jan Lelis, Idiosyncratic Ruby
10 New Features in Ruby 2.5
by Junichi Ito, Ruby programmer @ SonicGarden.jp
10 More New Features in Ruby 2.5
by Tom Lord, Software Developer from London
Performance Improvements in Ruby 2.5
by Jesus Castello, Ruby Guides
yield_self in Ruby 2.5
by Michał Łomnicki
Improved stacktrace display in Ruby 2.5
by Michał Łomnicki
Ruby 2.5 Series
by Amit Choudhary, Mohit Natoo et al @ BigBinary
Add your ruby 2.5 news byte »
Ruby Event News
Ruby on Ice - Jan 26-28th, 2018
Conference in Tegernsee, Bavaria, Germany
Paris.rb XXL - Jun 28+29th, 2018
Conference in Paris, France
European Ruby Conference (EuRuKo) 2018
Upcoming this summer in Vienna, Austria
Add your event news byte »

« Ruby Advent Calendar 2017

HANSON.parse, SON.parse, JSONX.parse

json-next library - Read Next Generation JSON Versions (HanSON, SON, JSONX/JSON11, etc.) with Comments, Unquoted Keys, Multi-Line Strings, Trailing Commas, Optional Commas, and More

github: json-next/json-next, rubygems: json-next, rdoc: json-next ++ more: comments on reddit, please!

What’s missing in JSON?

  1. Comments, Comments, Comments
  2. Unquoted Keys
  3. Multi-Line Strings
    • a) Folded – Folds Newlines
    • b) Unfolded
  4. Trailing Commas in Arrays and Objects

More:

Discussion

Fixing JSON - Comments, Please!

We can easily agree on what’s wrong with JSON, and I can’t help wondering if it’d be worth fixing it.

– Tim Bray (Fixing JSON)

XML already does everything JSON does! And there’s no way to differentiate between nodes and attributes! And there are no namespaces! And no schemas! What’s the point of JSON?

– Anonymous

We need to fix engineers that try to ‘fix JSON’, absolutely nothing is broken with JSON.

– Anonymous

What’s the json-next library?

The json-next library lets you convert and read (parse) next generation json versions including: HanSON e.g. HANSON.parse, SON e.g. SON.parse, JSONX e.g. JSONX.parse.

HanSON

HanSON - JSON for Humans by Tim Jansen et al

HanSON is an extension of JSON with a few simple additions to the spec:

Example:

{
  listName: "Sesame Street Monsters", // note that listName needs no quotes
  content: [
    {
      name: "Cookie Monster",
      /* Note the template quotes and unescaped regular quotes in the next string */
      background: `Cookie Monster used to be a
monster that ate everything, especially cookies.
These days he is forced to eat "healthy" food.`
    }, {
      // You can single-quote strings too:
      name: 'Herry Monster',
      background: `Herry Monster is a furry blue monster with a purple nose.
He's mostly retired today.`
    },    // don't worry, the trailing comma will be ignored
   ]
}

Use HANSON.convert to convert HanSON text to ye old’ JSON text:

{
  "listName": "Sesame Street Monsters",       
  "content": [
    { "name": "Cookie Monster",
       "background": "Cookie Monster used to be a\n ... to eat \"healthy\" food."
    },
    { "name": "Herry Monster",
      "background": "Herry Monster is a furry blue monster with a purple nose.\n ... today."
    }
  ]
}

Use HANSON.parse instead of JSON.parse to parse text to ruby hash / array / etc.:

{
  "listName" => "Sesame Street Monsters",
  "content" => [
     { "name" => "Cookie Monster",
       "background" => "Cookie Monster used to be a\n ... to eat \"healthy\" food."
     },
     { "name" => "Herry Monster",
       "background" => "Herry Monster is a furry blue monster with a purple nose.\n ... today."
    }
  ]
}

SON

SON - Simple Object Notation by Aleksander Gurin et al

Simple data format similar to JSON, but with some minor changes:

JSON is compatible with SON in a sense that JSON data is also SON data, but not vise versa.

Example:

{
  # Personal information

  "name": "Alexander Grothendieck"
  "fields": "mathematics"
  "main_topics": [
    "Etale cohomology"
    "Motives"
    "Topos theory"
    "Schemes"
  ]
  "numbers": [1 2 3 4]
  "mixed": [1.1 -2 true false null]
}

Use SON.convert to convert SON text to ye old’ JSON text:

{
  "name": "Alexander Grothendieck",
  "fields": "mathematics",
  "main_topics": [
    "Etale cohomology",
    "Motives",
    "Topos theory",
    "Schemes"
  ],
  "numbers": [1, 2, 3, 4],
  "mixed": [1.1, -2, true, false, null]
}

Use SON.parse instead of JSON.parse to parse text to ruby hash / array / etc.:


{
  "name" => "Alexander Grothendieck",
  "fields" => "mathematics",
  "main_topics" =>
    ["Etale cohomology", "Motives", "Topos theory", "Schemes"],
  "numbers" => [1, 2, 3, 4],
  "mixed" => [1.1, -2, true, false, nil]    
}

JSONX

JSON with Extensions or JSON v1.1 (a.k.a. JSON11 or JSON XI or JSON II)

Includes all JSON extensions from HanSON:

Plus all JSON extensions from SON:

Plus some more extra JSON extensions:

Example:

{
  #  use shell-like (or ruby-like) comments

  listName: "Sesame Street Monsters"   # note: comments after key-value pairs are optional  
  content: [
    {
      name: "Cookie Monster"
      // note: the template quotes and unescaped regular quotes in the next string
      background: `Cookie Monster used to be a
monster that ate everything, especially cookies.
These days he is forced to eat "healthy" food.`
    }, {
      // You can single-quote strings too:
      name: 'Herry Monster',
      background: `Herry Monster is a furry blue monster with a purple nose.
He's mostly retired today.`
    },    /* don't worry, the trailing comma will be ignored  */
   ]
}

Use JSONX.convert (or JSONXI.convert or JSON11.convert or JSONII.convert) to convert JSONX text to ye old’ JSON text:

{
  "listName": "Sesame Street Monsters",       
  "content": [
    { "name": "Cookie Monster",
       "background": "Cookie Monster used to be a\n ... to eat \"healthy\" food."
    },
    { "name": "Herry Monster",
      "background": "Herry Monster is a furry blue monster with a purple nose.\n ... today."
    }
  ]
}

Use JSONX.parse (or JSONXI.parse or JSON11.parse or JSONII.parse) instead of JSON.parse to parse text to ruby hash / array / etc.:

{
  "listName" => "Sesame Street Monsters",
  "content" => [
     { "name" => "Cookie Monster",
       "background" => "Cookie Monster used to be a\n ... to eat \"healthy\" food."
     },
     { "name" => "Herry Monster",
       "background" => "Herry Monster is a furry blue monster with a purple nose.\n ... today."
    }
  ]
}

Live Examples

require 'json/next'

text1 =<<TXT
{
  listName: "Sesame Street Monsters", // note that listName needs no quotes
  content: [
    {
      name: "Cookie Monster",
      /* Note the template quotes and unescaped regular quotes in the next string */
      background: `Cookie Monster used to be a
monster that ate everything, especially cookies.
These days he is forced to eat "healthy" food.`
    }, {
      // You can single-quote strings too:
      name: 'Herry Monster',
      background: `Herry Monster is a furry blue monster with a purple nose.
He's mostly retired today.`
    },    // don't worry, the trailing comma will be ignored
   ]
}
TXT

pp HANSON.parse( text1 )  # note: is the same as JSON.parse( HANSON.convert( text ))

resulting in:

{
  "listName" => "Sesame Street Monsters",
  "content" => [
     { "name" => "Cookie Monster",
       "background" => "Cookie Monster used to be a\n ... to eat \"healthy\" food."
     },
     { "name" => "Herry Monster",
       "background" => "Herry Monster is a furry blue monster with a purple nose.\n ... today."
    }
  ]
}

and


text2 =<<TXT
{
  # Personal information

  "name": "Alexander Grothendieck"
  "fields": "mathematics"
  "main_topics": [
    "Etale cohomology"
    "Motives"
    "Topos theory"
    "Schemes"
  ]
  "numbers": [1 2 3 4]
  "mixed": [1.1 -2 true false null]
}
TXT

pp SON.parse( text2 )  # note: is the same as JSON.parse( SON.convert( text ))

resulting in:

{
  "name" => "Alexander Grothendieck",
  "fields" => "mathematics",
  "main_topics" =>
    ["Etale cohomology", "Motives", "Topos theory", "Schemes"],
  "numbers" => [1, 2, 3, 4],
  "mixed" => [1.1, -2, true, false, nil]    
}

and

text3 =<<TXT
{
  #  use shell-like (or ruby-like) comments

  listName: "Sesame Street Monsters"   # note: comments after key-value pairs are optional  
  content: [
    {
      name: "Cookie Monster"
      // note: the template quotes and unescaped regular quotes in the next string
      background: `Cookie Monster used to be a
monster that ate everything, especially cookies.
These days he is forced to eat "healthy" food.`
    }, {
      // You can single-quote strings too:
      name: 'Herry Monster',
      background: `Herry Monster is a furry blue monster with a purple nose.
He's mostly retired today.`
    },    /* don't worry, the trailing comma will be ignored  */
   ]
}
TXT

pp JSONX.parse( text3 )   # note: is the same as JSON.parse( JSONX.convert( text ))
pp JSONXI.parse( text3 )  # note: is the same as JSON.parse( JSONXI.convert( text ))
pp JSON11.parse( text3 )  # note: is the same as JSON.parse( JSON11.convert( text ))
pp JSONII.parse( text3 )  # note: is the same as JSON.parse( JSONII.convert( text ))

resulting in:

{
  "listName" => "Sesame Street Monsters",
  "content" => [
     { "name" => "Cookie Monster",
       "background" => "Cookie Monster used to be a\n ... to eat \"healthy\" food."
     },
     { "name" => "Herry Monster",
       "background" => "Herry Monster is a furry blue monster with a purple nose.\n ... today."
    }
  ]
}

Bonus: More JSON Formats

See the Awesome JSON (What’s Next?) collection / page.


From the Ruby Advent Calendar 2017.