It is the expected behaviour.

The problem isn't what from-json is returning but what kind of assignment
you're doing to the result. Here's a simple version:

my @a = $[1,2,3]; say @a # [[1 2 3]]

Since from-json doesn't know what it's returning, (a string, a hash, an
array) it returns whatever it got as a single item. If you want to assign a
single item to a variable you should use a $ variable to avoid list
assignment:

my $a = $[1 2, 3]; say $a # [1 2 3]

Alternatively, if you know that the RHS is going to be an array you can
avoid list assignment by doing binding instead of assignment. This will
work regardless of the RHS's itemization

my @a := $[1, 2, 3]; say @a; # [1 2 3]
my @a := [1, 2, 3]; say @a; # [1 2 3]

Or you could use the alternatives you presented above.

Hash assignment is much less ambiguous in this situation. If there's one
value on the RHS it must be the hash you want to assign to (not an element
of the hash you want to create) regardless of its itemization.

LL



On Thu, Jun 1, 2017 at 7:52 AM Gabor Szabo <szab...@gmail.com> wrote:

> When converting an array to json and then back again, I need to use |
> or () in order to get back the original array in a @variable.
>
> This surprised me, especially as for hashes the roundtrip worked
> without any extra work.
> I was wondering if this is really the expected behaviour?
>
> Gabor
>
> use v6;
> use JSON::Fast;
> #use JSON::Tiny;
>
> my @elems1;
> @elems1.push: {
>     name => 'Foo',
>     id   => 1,
> };
>
> say @elems1.gist; # [{id => 1, name => Foo}]
>
> my $json_str = to-json @elems1;
> #say $json_str;
>
> my (@elems2) = from-json $json_str;
> say @elems2.gist;    # [{id => 1, name => Foo}]
>
> my @elems3 = | from-json $json_str;
> say @elems3.gist;     # [{id => 1, name => Foo}]
>
> my @elems4 = from-json $json_str;
> say @elems4.gist;    # [[{id => 1, name => Foo}]]
>

Reply via email to