Ruby trae soporte para JSON mediante la librería estándar json (gem incluida con Ruby MRI). Permite serializar (Ruby → JSON) y deserializar (JSON → Ruby) de forma muy directa.
Requisito en cada script:
require "json"
Ejemplo básico
require "json"
json_str = '{"nombre":"Ana","edad":28,"activo":true,"hobbies":["leer","correr"]}'
data = JSON.parse(json_str) # => {"nombre"=>"Ana", "edad"=>28, "activo"=>true, "hobbies"=>["leer","correr"]}
puts data["nombre"] # "Ana"
puts data["hobbies"].first # "leer"
# Convertir claves a símbolos
data_sym = JSON.parse(json_str, symbolize_names: true)
# => {nombre: "Ana", edad: 28, activo: true, hobbies: ["leer", "correr"]}
puts data_sym[:nombre]
# Manejo de errores al parsear
begin
JSON.parse('{nombre:"Ana"}') # inválido (faltan comillas en la clave)
rescue JSON::ParserError => e
warn "JSON inválido: #{e.message}"
end
to_json
y JSON.generate
require "json"
usuario = { nombre: "Luis", edad: 35, activo: false, tags: ["ruby", "json"] }
puts usuario.to_json # => {"nombre":"Luis","edad":35,"activo":false,"tags":["ruby","json"]}
puts JSON.generate(usuario) # idem
# Salida legible (pretty)
puts JSON.pretty_generate(usuario)
# {
# "nombre": "Luis",
# "edad": 35,
# "activo": false,
# "tags": [
# "ruby",
# "json"
# ]
# }
# También existen JSON.dump(obj, io = nil) y JSON.load, pero en general
# se prefieren JSON.generate / JSON.parse.
Escribir a archivo
require "json"
producto = { codigo: 101, descripcion: "Teclado mecánico", precio: 1200.5, disponible: true }
File.write("producto.json", JSON.pretty_generate(producto))
Leer desde archivo
require "json"
contenido = File.read("producto.json")
data = JSON.parse(contenido, symbolize_names: true)
puts data[:descripcion] # "Teclado mecánico"
require "json"
json_list = <<~JSON
[
{"codigo":201,"descripcion":"Monitor 24","precio":1500.0},
{"codigo":202,"descripcion":"Notebook","precio":2500.5}
]
JSON
productos = JSON.parse(json_list, symbolize_names: true)
productos.each { |p| puts "#{p[:codigo]} - #{p[:descripcion]} ($#{p[:precio]})" }
Para convertir instancias a JSON, definí as_json
y/o to_json
.
as_json
retorna una estructura Ruby serializable (Hash/Array/valores primitivos).to_json
llama internamente a as_json
(si existe).require "json"
class Producto
attr_accessor :codigo, :descripcion, :precio, :disponible, :tags
def initialize(codigo:, descripcion:, precio:, disponible:, tags: [])
@codigo = codigo
@descripcion = descripcion
@precio = precio
@disponible = disponible
@tags = tags
end
def as_json(*)
{ codigo: @codigo, descripcion: @descripcion, precio: @precio, disponible: @disponible, tags: @tags }
end
def to_json(*opts)
as_json.to_json(*opts)
end
end
p1 = Producto.new(codigo: 1, descripcion: "Mouse", precio: 850.75, disponible: true, tags: ["oferta"])
puts JSON.pretty_generate(p1)
# JSON → objeto propio (deserializar)
hash = JSON.parse('{"codigo":1,"descripcion":"Mouse","precio":850.75,"disponible":true,"tags":["oferta"]}', symbolize_names: true)
p_from_json = Producto.new(**hash) # usa keywords para mapear
# Si el JSON puede traer claves extra, filtralas antes o usá slice en Rails/ActiveSupport.
JSON no tiene tipo fecha. En Ruby se suelen serializar como ISO 8601 (string).
require "json"
require "date"
pedido = {
id: 10,
creado_en: Time.now.iso8601, # "2025-09-09T13:27:00-03:00"
entrega_en: Date.today.next_day.iso8601 # "2025-09-10"
}
puts JSON.pretty_generate(pedido)
# Para parsear de vuelta:
hash = JSON.parse(pedido.to_json, symbolize_names: true)
creado_time = Time.iso8601(hash[:creado_en])
entrega_date = Date.iso8601(hash[:entrega_en])
Para grandes volúmenes, usá JSON::Stream
(gem externa) o procesá chunk a chunk.
Con estándar puro, podés usar JSON::Parser
sobre strings grandes.
NDJSON (JSON Lines) simple
# Escribir
File.open("items.ndjson", "w") do |f|
1.upto(3) do |i|
f.puts({ id: i, nombre: "Item #{i}" }.to_json)
end
end
# Leer línea a línea
File.foreach("items.ndjson") do |line|
obj = JSON.parse(line, symbolize_names: true)
puts obj[:nombre]
end
require "json"
require "net/http"
require "uri"
uri = URI("https://example.com/api/productos")
# GET (leer JSON)
resp = Net::HTTP.get_response(uri)
if resp.is_a?(Net::HTTPSuccess)
data = JSON.parse(resp.body, symbolize_names: true)
p data
end
# POST (enviar JSON)
nuevo = { codigo: 300, descripcion: "Parlantes", precio: 999.99 }
req = Net::HTTP::Post.new(uri, { "Content-Type" => "application/json" })
req.body = JSON.generate(nuevo)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
res = http.request(req)
puts res.code
En apps web modernas (Rails/Sinatra), suele usarse Faraday / HTTParty o el cliente de Rails.
symbolize_names: true
si preferís símbolos; caso contrario, strings.JSON.pretty_generate
para logs y depuración, JSON.generate
para producción (más compacto).JSON::ParserError
.as_json/to_json
en tus clases cuando necesites control fino.require "json"
require "net/http"
require "uri"
# 1) Generar y guardar
inventario = [
{ codigo: 1, descripcion: "Teclado", precio: 1200.5, disponible: true },
{ codigo: 2, descripcion: "Mouse", precio: 850.75, disponible: false }
]
File.write("inventario.json", JSON.pretty_generate(inventario))
# 2) Leer de archivo
data = JSON.parse(File.read("inventario.json"), symbolize_names: true)
puts "Productos: #{data.size}"
# 3) Enviar a una API
uri = URI("https://httpbin.org/post")
req = Net::HTTP::Post.new(uri, { "Content-Type" => "application/json" })
req.body = JSON.generate(data)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
res = http.request(req)
puts "POST status: #{res.code}"
respuesta = JSON.parse(res.body)
puts "Echo length: #{respuesta.dig('json')&.size}"
JSON.parse
— JSON.generate
/ obj.to_json
son tus básicos.JSON::ParserError
.pretty_generate
para legibilidad, symbolize_names
para símbolos.as_json/to_json
en clases propias.Content-Type: application/json
.