Camelia

Data serialization with JSON in Perl 6

JSON is one of the most common ways to communicate between applications that might have been written in different languages. Especially in web applications where the code running in the browser is usually in a different language than the code running on the server.

However JSON can be great even if both the sender and the receiver are in the same language. In our case in Perl 6.

Note! This site is about Perl 6.
If you are looking for a solution for Perl 5, please check out the Perl 5 tutorial.

There are basically two complex data structures that need serialization and deserialization. Hashes (or Associative Arrays, or Dictionaries) on one hand and Arrays (or Lists) on the other hand.

In Perl 6, due to the special behavior of the assignment, we need to be careful as the deserialization needs to be a bit different in the two cases.

Round trip: Serializing and deserializing hashes

The JSON::Fast module exports the to-json and from-json function that can be use to convert a Perl 6 data structure to JSON and to convert from a JSON string to a Perl 6 data structure.

examples/json_hash.pl

use v6;
use JSON::Fast;

my %person1 =
    name => 'Foo',
    id   => 42,
;

say %person1.perl;
say %person1.^name;
say %person1<name>;
say %person1<id>;

say '';
my $json_str = to-json %person1;
say $json_str;

say '';
my %person2 = from-json $json_str;
say %person2.perl;
say %person2.^name;
say %person2<name>;
say %person2<id>;

say '';
my %person3 := from-json $json_str;
say %person3.perl;
say %person3.^name;
say %person3<name>;
say %person3<id>;



The output looks like this:

{:id(42), :name("Foo")}
Hash
Foo
42

{
  "name": "Foo",
  "id": 42
}

{:id(42), :name("Foo")}
Hash
Foo
42

{:id(42), :name("Foo")}
Hash
Foo
42

The .perl method displays the Hash in a different representation than the way we created it, but that's still the same hash. You can also notice that both the regular assignment = and the binding assignment := works the same way.

Round trip: Serializing and deserializing arrays

With arrays we need to be a bit more careful.

examples/json_array.pl

use v6;
use JSON::Fast;

my @color1 = 'Blue', 'White', 'Green';
say @color1.perl;

my $json_str = to-json @color1;
say $json_str;

my @color2 = from-json $json_str;
say @color2.perl;

my @color3 = | from-json $json_str;
say @color3.perl;

my @color4 := from-json $json_str;
say @color4.perl;

The output looks like this:

["Blue", "White", "Green"]
[
  "Blue",
  "White",
  "Green"
]
[["Blue", "White", "Green"],]
["Blue", "White", "Green"]
["Blue", "White", "Green"]

The serialization goes well, the JSON string looks as we expect, but when we convert the JSON string back to Perl data structure and assign it to an array, we get an array inside another array. Not what we started with.

The problem, as explained by Lloyd Fournier on the perl6-users mailing list, is not with what from-json returns, but the way the assignment works.

from-json returns the data structure as a single item. When we put that single item in an array it became a single item in the array. Thus we got an array of an array. Not what we started with.

We have (at least) two ways to solve this: We can use the prefix | operator to flatten the list.

Alternatively we can use :=, the binding assignment operator.

In both cases we get back the data structure we started with.

Conclusion

JSON can be used for serialization and deserialization of Perl 6 data structures as well, but in the deserialization part we need to make a decision. Either we remember to write different code for hash and array deserialization (= for hash and = | for array) or we use the binding assignment for both: :=.


The Perl 6 Tricks and Treats newsletter has been around for a while. If you are interested to get special notification when there is new content on this site, it is the best way to keep track:
Email:
Full name:
This is a newsletter temporarily running on my personal site (szabgab.com) using Mailman, till I implement an alternative system in Perl 6.
Gabor Szabo
Written by Gabor Szabo

Published on 2017-06-02



Comments

In the comments, please wrap your code snippets within <pre> </pre> tags and use spaces for indentation.
comments powered by Disqus
Suggest a change
Elapsed time: 2.307574

Perl 6 Tricks and Treats newsletter

Register to the free newsletter now, and get updates and news.
Email:
Name: