Skip to content
AgileLogics
5 min read

Working with JSON and YAML

Prerequisites: Hashes, Working with files

JSON is the most common format for sending data between programs — every web API speaks it. YAML is a more human-friendly format used for configuration files. Ruby's standard library handles both.

Ruby → JSON

require "json"

user = { name: "Ada", languages: ["Ruby", "C"], active: true, manager: nil }

puts user.to_json
puts JSON.pretty_generate(user)
{"name":"Ada","languages":["Ruby","C"],"active":true,"manager":null}
{
  "name": "Ada",
  "languages": [
    "Ruby",
    "C"
  ],
  "active": true,
  "manager": null
}

nil becomes null, and symbol keys become strings — JSON has no symbols.

JSON → Ruby

require "json"

text = '{"name": "Ada", "age": 36, "tags": ["admin"]}'

data = JSON.parse(text)
p data["name"]

data = JSON.parse(text, symbolize_names: true)
p data[:age]
p data
"Ada"
36
{name: "Ada", age: 36, tags: ["admin"]}

By default, parsed keys are strings. symbolize_names: true turns them into symbols, which matches Ruby style and works with pattern matching.

Invalid JSON raises JSON::ParserError — rescue it whenever the text comes from outside your program. The JSON Formatter is handy for inspecting a payload that won't parse.

YAML

require "yaml"

config = YAML.safe_load(<<~YAML, symbolize_names: true)
  app:
    name: Shop
    port: 3000
  features:
    - search
    - checkout
YAML

p config[:app][:port]
p config[:features]
3000
["search", "checkout"]

Use YAML.safe_load (or YAML.load_file for files) for YAML you didn't write yourself. It only builds plain data — hashes, arrays, strings, numbers — and refuses to create arbitrary Ruby objects, which could otherwise be a security hole.

Common mistakes

  • Parsing JSON and reading data[:name] — nil, because the keys are strings unless you passed symbolize_names: true.
  • Using YAML.unsafe_load on untrusted input.