API에 대한 JSON 메시지를 만들려고 할 때 간단하다고 생각되는 작업을 수행하는 데 어려움을 겪고 있습니다. 다음과 같은 메시지를 작성해야했습니다.
{ "list": [ { "foo": 1, "bar": 2 } ] }
그러나 첫 시도는 효과가 없었습니다.
say to-json { foo => [ { a => 1, b => 2 } ] };
# {"foo":[{"a":1},{"b":2}]}
일을 단순화하려고하면 더 혼란 스럽습니다.
say { foo => [ { a => 1 } ] };
# {foo => [a => 1]}
# Note that this is not JSON, but I expected to see curly braces
그런 다음 임시 변수를 사용하려고 시도했지만 작동했습니다.
my @list = { a => 1 };
say to-json { foo => @list };
# {"foo":[{"a":1}]}
my %hash = ( a => 1 );
say to-json { foo => [ %hash ] };
# {"foo":[{"a":1}]}
무슨 일이야?
추가 임시 변수없이 원하는 결과를 얻을 수있는 방법이 있습니까?
답변
단일 인수 규칙을 발견했습니다 . 라쿠의 수많은 구성은 그들이 제공하는 주장을 반복 할 것입니다. 여기에는 [...]
배열 작성기가 포함됩니다 . 이것이 우리가 말할 때의 이유입니다.
say [1..10];
우리는 1이 아닌 10 개의 요소를 포함하는 배열을 얻습니다.
say [[1,2]];
내부 배열이없는 것처럼 [1,2]
결과를 반복합니다 [1,2]
. A Hash
는 쌍으로 반복되므로 다음과 같습니다.
{ foo => [ { a => 1, b => 2 } ] }
실제로 다음을 생성합니다.
{ foo => [ a => 1, b => 2 ] }
즉, 배열에는 쌍이 있습니다. 그런 다음 JSON 시리얼 라이저는 각 쌍을 하나의 요소로 직렬화합니다.
해결책은 단일 요소 iterable을 생성하는 것입니다. 삽입 ,
연산자는 목록을 생성하는 것이므로 다음을 사용할 수 있습니다.
say to-json { foo => [ { a => 1, b => 2 }, ] };
# note the , here ^
그런 다음 반복되는 단일 인수는 해시가있는 1 요소 목록이며 원하는 결과를 얻습니다.
기억하기 쉬운 방법 : 실제로 목록을 채울 단일 iterable을 지정하지 않는 한 단일 요소 목록으로도 목록, 배열 또는 해시의 값을 지정할 때는 항상 쉼표를 사용하십시오.