Al intentar crear un mensaje JSON para una API, me encontré luchando por hacer algo que pensé que sería simple. Necesitaba crear un mensaje como el siguiente:
{ "list": [ { "foo": 1, "bar": 2 } ] }
Sin embargo, mi primer intento no funcionó:
say to-json { foo => [ { a => 1, b => 2 } ] };
# {"foo":[{"a":1},{"b":2}]}
Intentar simplificar las cosas me confundió aún más:
say { foo => [ { a => 1 } ] };
# {foo => [a => 1]}
# Note that this is not JSON, but I expected to see curly braces
Luego intenté usar algunas variables temporales, y eso funcionó:
my @list = { a => 1 };
say to-json { foo => @list };
# {"foo":[{"a":1}]}
my %hash = ( a => 1 );
say to-json { foo => [ %hash ] };
# {"foo":[{"a":1}]}
¿Que está pasando aqui?
¿Y hay alguna manera de lograr el resultado deseado sin una variable temporal adicional?
say to-json { foo => [ { a => 1 } ] };
debería mostrar algo como{"foo":[{"a":1}]}
, no{"foo":["a":1]}
. Este último es un error tipográfico, ¿verdad? Si no, ¿quésay $*PERL.compiler.version;
dice?say to-json { foo => [ a => 1 ] }
salidas,{"foo":[{"a":1}]}
así que quién sabe lo que escribí cuando lo obtuve, si alguna vez lo hice. ¡Culpa mía!Respuestas:
Has descubierto la regla del argumento único . Numerosas construcciones en Raku iterarán el argumento que se les proporciona. Esto incluye el
[...]
compositor de matrices. Es por eso que cuando decimos:Obtenemos una matriz que contiene 10 elementos, no 1. Sin embargo, también significa que:
Itera el
[1,2]
, y por lo tanto resulta en[1,2]
- como si la matriz interna no estuviera allí. AHash
itera a sus pares, por lo tanto:Actualmente produce:
Es decir, la matriz tiene los pares. El serializador JSON serializa cada par como un objeto de un elemento.
La solución es producir un elemento único iterable. El
,
operador infijo es lo que produce listas, por lo que podemos usar eso:Entonces, el argumento único que debe iterarse es una lista de 1 elemento con un hash, y obtiene el resultado que desea.
Una forma fácil de recordarlo: siempre use comas finales al especificar los valores de una lista, matriz o hash, incluso con una lista de elementos únicos, a menos que realmente esté especificando el único iterable desde el cual llenarlo.
fuente