1. Introduction

Camelia, the Perl 6 mascot (Image source: Wikipedia

Perl 6 is the latest version of the Perl language—a long-time favorite scripting language of hackers and programmers everywhere. Perl itself is one of the first scripting languages in widespread use and has been used mainly in GNU/Linux systems by system administrators to automate tasks. Hackers prefer Perl because it’s easy to write one-off scripts. And with CPAN, you can find any module you need to get the job done.

Perl 6 has taken a long time to show up and only in Christmas 2015 did it get to a point where it can start to be widely used again. Perl 6 is ready to compete against Python and Ruby—the other dynamic scripting languages that have replaced Perl 5.

In this article, we’re going to do something very basic with Perl 6: reading and writing JSON files and objects. We will serialize and deserialize objects and hashes, into and out of, JSON objects.

We will lay out the code with a brief explanation and the code will be explained line by line. Links to further information about the Perl 6 language keywords or functions being used will also be included.

This tutorial is aimed at Perl 6 beginners.

Want to learn more about Perl? Get help from Perl experts

2. Installation and set up

There are two ways to install Perl 6: the easy way, and the slightly less easy way. We will also be installing the Perl 6 package manager, Panda.

If you’ve already set up Perl 6, you can find new modules and packages in the Perl 6 modules directory.

2.1. The Easy Way: RakudoBrew

Some of you may want to get up and running quickly with Perl 6. In that case, you can try using RakudoBrew. It is a shell script for GNU/Linux and Mac OS X which makes it easy to install Rakudo/MoarVM and Panda (Perl Package Manager).

2.1.1. RakudoBrew for GNU/Linux

Here is the command to run to use RakudoBrew on GNU/Linux:

git clone https://github.com/tadzik/rakudobrew ~/.rakudobrew echo 'export PATH=~/.rakudobrew/bin:$PATH' >> ~/.bashrc source ~/.bashrc

2.1.2 RakudoBrew for Mac OS X

Here is the command to run in the Terminal on Mac OS X to use RakudoBrew:

git clone https://github.com/tadzik/rakudobrew ~/.rakudobrew echo 'export PATH=~/.rakudobrew/bin:$PATH' >> ~/.bash_profile source ~/.bash_profile

2.1.3 Installing Rakudo and Panda

After RakudoBrew is installed you can use the following commands to install Perl 6 and Panda, the package manager:

rakudobrew build moar rakudobrew build panda

2.2 The Slightly Less Easy Way

2.2.1 Installing Perl 6

The first step is to get Perl 6 installed. Since it isn’t widely used yet, you may have to go through some extra steps to get it installed on your operating system.

The primary (and popular) Perl 6 implementation is Rakudo Perl 6. You can follow the instructions here to install Rakudo.

On Fedora, I was able to install it like this:

dnf install rakudo

2.2.2 Installing Panda, Perl6 Package Manager

The instructions for install Panda are available here.

These are the commands:

git clone --recursive git://github.com/tadzik/panda.git cd panda perl6 bootstrap.pl

This, of course, requires that Perl6 is already installed.

2.3 Installing the JSON::Tiny package

With Perl 6 and its package manager installed, we can install the JSON library that we are going to use to read and write JSON objects. The library is called JSON::Tiny and while there are others, this particular library is very simple and easy to use which is perfect for us.

You can install the package with this command:

panda install JSON::Tiny

3. Loading a JSON object from a string

Let’s jump right in and look at some code. We are going to be creating a JSON object within a string, parsing that JSON string and turning it into a hash.

Create a new file named load-json-from-string.pl6 and type in the following source code:

use JSON::Tiny; my $json_as_string = '{"carType":"BMW", "quantity":3, "price":"32000.00"}'; my %json = from-json $json_as_string; my $description = q:to/END/; The car type is %s. There are %d cars available. The price is $%.2f. END say $description.sprintf(%json<carType>, %json<quantity>, %json<price>);

You will see that in the first line we are importing the JSON::Tiny package with the use keyword.

In the next line, we are storing a JSON object as a string. The my keyword is used to declare a local variable. The JSON object has three fields, carType, quantity, and price. The carType and price are strings, and the quantity is an integer. When we parse that JSON object into a hash, we expect that the types of the fields are preserved.

After we imported the JSON::Tiny library, we gained access to two functions: to-json and from-json . In this case, we’re interested in loading a JSON object from a string so we use the from-json function to convert the string. You can see how to do this in line 3.

What’s stored in %json is a hash table (also known as a dictionary or map). There are three keys in this hash table that match the JSON fields, “carType”, “quantity”, and “price”.

Next, we define the description of the object we will be printing out. We use a heredoc which will be familiar to those programmers who have used Perl before. A heredoc is a way to define a multi-line string. If you’re a Perl user, you will notice that the syntax to start a heredoc has changed.

In the description, we use a few special formatting options to indicate where the type of data we will be printing. The formatting options are used by the sprintf function. In line 9 we will be printing out the result of using sprintf to supply values to the format string description .

Let’s run the program:

perl6 load-json-from-string.pl

We will get the following output:

The car type is BMW. There are 3 cars available. The price is $32000.00.

So that’s how we parse a JSON object from a string into a hash table and access and display the keys and values in that hash table.

4. Creating a JSON object from a hash table

Now we are going to create a hash table and then turn it into a JSON object.

Create a new file named hash-into-json.pl6 .

Here is how it will look (explanation for the code is below):

use JSON::Tiny; my %dealership = cars => ['Ford', 'BMW'], avgTestDrivesPerWeek => 15.1; my $json_as_string = to-json %dealership; say $json_as_string; say 'Is it a string? ' ~ ($json_as_string ~~ Str);

As before, we import the JSON::Tiny module.

Then we create the hash table. The types of data stored are basic data types like strings and numbers and arrays. In our example, we’re storing a list of strings naming the cars that are in the car dealership, and we’re also storing the average number of test drives per week.

Next, we use the handy to-json function provided by JSON::Tiny to convert the hash table into a JSON object. We store the result in $json_as_string .

Finally, we display the JSON object string.

In the last line, we are using the string concatenation operator, ~ , to create the sentence and printing out true or false depending on if the $json_as_string variable is of the string type.

Now let’s run the program:

perl6 hash-into-json.pl6

You should see this result:

{ "avgTestDrivesPerWeek" : 15.1, "cars" : [ "Ford", "BMW" ] } Is it a string? True

5. Creating a JSON object from a class object

In the previous example, we converted a simple hash table into a JSON object. Things become more interesting when we want to convert other types of objects into JSON objects.

To do this, we need to define a new method that matches the type of the class and has the same name as the to-json function. This is known as multiple dispatch where the method that is called is based on the arguments supplied to that function.

In JSON::Tiny, when the to-json method is called with a boolean value, it will check the value and print out either “true” or “false”. The method called will be the one where the argument is of the Bool type.

JSON::Tiny defines a few other methods for other types of arguments:

• Real (numbers)

• Str (string)

• Bool (boolean)

• Associative (maps, hash tables)

• Positional (lists, arrays)

So we have to do the same thing and define our own to-json method that is dispatched when the argument given to it matches our class.

Before we do anything we have to import the JSON::Tiny package:

use JSON::Tiny;

Let’s create our class. It is an art gallery class that stores the name of the gallery, the year it was established and an array of paintings it has sold:

class ArtGallery { has Str $.name is required; has Int $.yearEstablished; has Str @.paintings-sold; }

Now let’s use multiple dispatch and define the to-json method that accepts a defined instance of the ArtGallery class:

multi to-json(ArtGallery:D $d) { my %h = name => $d.name, year_established => $d.yearEstablished, paintings_sold => $d.paintings-sold; to-json %h; }

Next, let’s define an instance of the ArtGallery class. It will be named Cool Art Gallery , it was established in the year 1812 and it has sold three paintings. Of special note here is that the list of paintings sold is separated by semi-colons rather than commas (see the Perl 6 List Literals documentation for more information about list creation syntax).

my $art_gallery = ArtGallery.new( :name('Cool Art Gallery'), :yearEstablished(1812), :paintings-sold('Woman with a parasol'; 'Beach in Pourville'; 'The Magpie') );

Then, print it out as a JSON object string:

say to-json($art_gallery);

Run the program:

perl6 object-to-json.pl6

The output of running this program is this:

{ "name" : "Cool Art Gallery", "year_established" : 1812, "paintings_sold" : [ "Woman with a parasol", "Beach in Pourville", "The Magpie" ] }

The source code for the whole program looks like this:

# object-to-json.pl6 use JSON::Tiny; class ArtGallery { has Str $.name is required; has Int $.yearEstablished; has Str @.paintings-sold; } multi to-json(ArtGallery:D $d) { my %h = name => $d.name, year_established => $d.yearEstablished, paintings_sold => $d.paintings-sold; to-json %h; } my $art_gallery = ArtGallery.new( :name('Cool Art Gallery'), :yearEstablished(1812), :paintings-sold('Woman with a parasol'; 'Beach in Pourville'; 'The Magpie') ); say to-json($art_gallery);

6. Saving a JSON object to a file

In the next example, we are going to save the class as a JSON object into a file. We’re going to re-use the previous code for the ArtGallery class definition, the to-json definition and create an instance of an ArtGallery.

The new part that we’re adding is writing (also known as saving) the JSON object string to a file.

my $fh = open 'art_gallery.json', :w; $fh.say(to-json($art_gallery)); $fh.close;

The shorter way of saving a string to a file is:

spurt 'art_gallery.json', to-json($art_gallery);

The Perl 6 Documentation on Writing Files is very informative and provides more examples of doing this.

The source code for the whole program looks like this:

# object-to-json-file.pl6 use JSON::Tiny; class ArtGallery { has Str $.name is required; has Int $.yearEstablished; has Str @.paintings-sold; } multi to-json(ArtGallery:D $d) { my %h = name => $d.name, year_established => $d.yearEstablished, paintings_sold => $d.paintings-sold; to-json %h; } my $art_gallery = ArtGallery.new( :name('Cool Art Gallery'), :yearEstablished(1812), :paintings-sold('Woman with a parasol'; 'Beach in Pourville'; 'The Magpie') ); my $fh = open 'art_gallery.json', :w; $fh.say(to-json($art_gallery)); $fh.close;

When we run the code, it will create an ArtGallery object, convert it to JSON and save it to art_gallery.json .

Run the code like this:

perl6 object-to-json-file.pl6

You can check if it worked by opening the file art_gallery.json . It should look like this:

{ "name" : "Cool Art Gallery", "year_established" : 1812, "paintings_sold" : [ "Woman with a parasol", "Beach in Pourville", "The Magpie" ] }

Wrapping up

In this tutorial, we’re introduced to Perl 6 by reading and writing JSON files and objects. Hopefully, this will pick up your interest with Perl and continue learning more about it.

Other related tutorials and tips