Módulo JSON
El módulo JSON convierte texto JSON en valores de JARU (mapas, listas, números, cadenas y booleanos) y al revés. Sirve para leer lo que contesta una API con Http, guardar la configuración de un programa en un fichero con File o mandar datos por MQTT.
use JSON

Funciona igual en Windows y en todas las placas.
Funciones
| Función | Qué hace | Devuelve |
|---|---|---|
JSON.parse(texto) | Lee un texto JSON | El valor: un mapa, una lista, un número, una cadena o un booleano |
JSON.stringify(valor) | Escribe un valor como texto JSON, en una línea | Una cadena |
JSON.stringify(valor, sangria) | Lo mismo, con una línea por elemento y sangria espacios por nivel | Una cadena |
parse(texto)
Lee el texto JSON texto y devuelve lo que representa. Un objeto JSON se convierte en un mapa, y sus valores, en los de esta tabla:
| En el JSON | En JARU |
|---|---|
Objeto { … } | Un mapa, con las claves como cadenas |
Array [ … ] | Una lista |
| Número sin decimales | Un entero |
Número con decimales o con exponente (8.5, 3.0, 1e3) | Un decimal |
| Cadena | Una cadena. Los escapes (\n, \", \u00e9…) ya vienen convertidos. |
true y false | true y false |
null | nil |
Los valores de un mapa se leen con corchetes, m["clave"], y los de una lista, con su posición, l[0] (ver Listas, mapas y arrays):
use JSON
var texto = '{"nombre": "Ana", "edad": 25, "notas": [7, 8.5], "dir": {"calle": "Mayor", "num": 3}}'
var persona = JSON.parse(texto)
println(persona["nombre"]) // Ana
println(persona["notas"][1]) // 8.5
println(persona["dir"]["calle"]) // Mayor
var lista = JSON.parse("[1, 2, 3]")
println(lista.size()) // 3
El texto también puede ser un valor suelto: JSON.parse("42") devuelve el entero 42, y JSON.parse('"hola"'), la cadena hola.
Es un JSON estricto, con una excepción: admite una coma de más al final de una lista o de un objeto ([1, 2,] da [1, 2]). No admite comillas simples, claves sin comillas ni comentarios. Si una clave se repite, se queda el último valor.
Si el texto no se puede leer, lanza una excepción, que se captura con try (ver Errores y excepciones):
| Error | Mensaje | Cuándo |
|---|---|---|
ERR_INVALID_VALUE | String is not valid JSON. | El texto no es JSON válido. |
ERR_INVALID_VALUE | Argument of parse() is an empty string. | El texto está vacío. |
ERR_INVALID_VALUE | JSON object could not be processed. | El texto es solo null. |
ERR_TYPE_MISMATCH | Argument of parse() must be a string. | No le pasas una cadena. |
ERR_INVALID_ARG_NUMBER | parse() expects 1 argument, got 2. | No le pasas un argumento. |
use JSON
try
var datos = JSON.parse("{nombre: 1}")
catch (var e)
println(e) // ERR_INVALID_VALUE: String is not valid JSON.
end
stringify(valor, sangria)
Escribe valor como texto JSON y lo devuelve en una cadena. sangria es opcional:
- Sin
sangria, todo va en una línea, con un espacio detrás de cada:y cada,. - Con
sangria, un entero, cada elemento va en su línea, consangriaespacios más por cada nivel. Con0, una línea por elemento y sin sangría.
use JSON
var lectura = {"sensor": "t1", "valor": 21.5, "ok": true, "fallos": nil}
println(JSON.stringify(lectura))
println(JSON.stringify([1, 2.0, "dos"])) // [1, 2, "dos"]
{"valor": 21.5, "fallos": null, "sensor": "t1", "ok": true}
[1, 2, "dos"]
Con sangría, JSON.stringify({"lista": [1, 2]}, 2) da:
{
"lista": [
1,
2
]
}
Cada valor de JARU se escribe así:
| En JARU | En el JSON |
|---|---|
| Mapa | Un objeto. Sus claves se escriben como cadenas: un entero, como 1, sale "1" (y JSON.parse lo lee como esa cadena); true y false, "true" y "false"; y nil, "null". Con otra clave, como un decimal, lanza ERR_INVALID_VALUE. |
| Lista | Un array |
| Entero | Un número |
| Decimal | Un número con 6 cifras significativas: 1 / 3 sale 0.333333, y 3000000000.0, 3e+09. Un decimal sin parte decimal se escribe como entero: 2.0 sale 2. |
| Cadena | Una cadena, con ", \ y los saltos de línea y tabuladores escritos como escapes |
true y false | true y false |
nil | null |
El orden de las claves de un objeto no es el del mapa: en el ejemplo de arriba, valor sale antes que sensor.
Errores (excepciones):
| Error | Mensaje | Cuándo |
|---|---|---|
ERR_INVALID_VALUE | Object is not serializable to JSON. | El valor, o uno de los que lleva dentro una lista o un mapa, no es de los de la tabla: una instancia de una clase, un array {…}, un bloque de Bytes, una función… O un mapa tiene una clave que no es una cadena, un entero, un booleano ni nil. |
ERR_TYPE_MISMATCH | Argument 2 of stringify() (indent) must be an integer. | sangria no es un entero. |
ERR_INVALID_ARG_NUMBER | stringify() expects 1 or 2 arguments, got 0. | No le pasas uno o dos argumentos. |
Ejemplo completo
Guarda la configuración de un programa en un fichero y la vuelve a leer:
use JSON, File
// La configuración de serie
var config = {"nombre": "Sensor 1", "intervalo": 30, "umbrales": [18, 26], "activo": true}
// Guardarla en un fichero, con sangría para que se lea bien
var f = File.open("config.json", "w")
f.write(JSON.stringify(config, 2))
f.close()
// Leerla otra vez
var g = File.open("config.json", "r")
var leida = JSON.parse(g.read())
g.close()
println(leida["nombre"]) // Sensor 1
println(leida["umbrales"][1]) // 26
leida["intervalo"] = 60
println(JSON.stringify(leida))
La última línea imprime:
{"nombre": "Sensor 1", "umbrales": [18, 26], "intervalo": 60, "activo": true}
Trampas y problemas conocidos
- Los valores, con corchetes. Un objeto JSON es un mapa: su valor se lee con
m["nombre"], no conm.nombre. - Decimales que no son iguales. Al leer un decimal, puede salir distinto en la última cifra del mismo número escrito en el programa:
JSON.parse("1.68") == 1.68esfalse. Para comparar decimales, mira si la diferencia es muy pequeña. - Decimales con 6 cifras.
stringifyredondea los decimales a 6 cifras significativas. Si necesitas más, escribe el número como cadena. - Enteros grandes. Los enteros de JARU son de 32 bits: un número sin decimales de más de 2147483647 se da la vuelta al leerlo (
[3000000000]da[-1294967296]). Escríbelo con decimales (3000000000.0) para que llegue como decimal. nullsolo no se lee.JSON.parse("null")da error. Dentro de un objeto o una lista sí: llega comonil.
Todos los problemas conocidos de JARU, juntos, están en Problemas conocidos.