Sun, 21 Sep 2008

Strings, Arrays, Hashes;

Permanent link


"Perl 5 to 6" Lesson 01 - Strings, Arrays, Hashes;




    my $five = 5;
    print "an interpolating string, just like in perl $five\n";
    say 'say() adds a newline to the output, just like in perl 5.10';

    my @array = 1, 2, 3, 'foo';
    my $sum = @array[0] + @array[1];
    if $sum > @array[2] {
        say "not executed";
    my $number_of_elems = @array.elems;     # or +@array
    my $last_item = @array[*-1];

    my %hash = foo => 1, bar => 2, baz => 3;
    say %hash{'bar'};                       # 2
    say %hash<bar>;                         # same with auto-quoting
    # this is an error: %hash{bar}
    # (it tries to call the subroutine bar(), which is not declared


Perl 6 is just like Perl 5 - only better. Statements are separated by semicolons. After the last statement in a block and after a closing curly brace at the end of a line the semicolon is optional.

Variables still begin with a sigil (like $, @, %), and many Perl 5 builtins are still mostly unchanged in Perl 6.


String literals are surrounded by double quotes (in which case they are interpolating), or with single quotes. Basic backslash escapes like \n work just like in Perl 5.

However the interpolation rules have changed a bit. The following things interpolate

    my $scalar = 6;
    my @array = 1, 2, 3;
    say "Perl $scalar";         # 'Perl 6'
    say "An @array[]";          # 'An 1 2 3', a so-called "Zen slice"
    say "@array[1]";            # '2'
    say "Code: { $scalar * 2 }" # 'Code: 12'

Arrays and hashes only interpolate if followed by an index (or a method call that ends in parenthesis, like "some $obj.method()"), an empty index will interpolate the whole data structure.

A block in curly braces is executed as code, and the result is interpolated.


Array variables still begin with the @ sigil. And they always do, even when accessing stored items, ie. when an index is present.

    my @a = 5, 1, 2;            # no parens needed anymore
    say @a[0];                  # yes, it starts with @
    say @a[0, 2];               # slices also work

Lists are constructed with the Comma operator. 1, is a list, (1) isn't. A special case is () which is how you spell the empty list.

Since everything is an object, you can call methods on arrays:

    my @b = @a.sort;
    @b.elems;                   # number of items
    if @b > 2 { say "yes" }     # still works
    @b.end;                     # number of last index. Replaces $#array
    my @c ={$_ * 2 });  # map is also a method, yes

There is a short form for the old qw/../ quoting construct:

    my @methods = <shift unshift push pop end delete sort map>;


While Perl 5 hashes are even sized lists when viewed in list context, Perl 6 hashes are lists of pairs in that context. Pairs are also used for other things, like named arguments for subroutines, but more on that later.

Just like with arrays the sigil stays invariant when you index it. And hashes also have methods that you can call on them.

    my %drinks =
        France  => 'Wine',
        Bavaria => 'Beer',
        USA     => 'Coke';

    say "The people in France love ",  %drinks{'France'};
    my @countries = %drinks.keys.sort;

Note that when you access hash elements with %hash{...}, the key is not automatically quoted like in Perl 5. So %hash{foo} doesn't access index "foo", but calls the function foo(). The auto quoting isn't gone, it just has a different syntax:

    say %drinks<Bavaria>;

Final Notes

Most builtin methods exist both as a method and as a sub. So you can write both sort @array and @array.sort.

Finally you should know that both [..] and {...} (occurring directly after a term) are just subroutine calls with a special syntax, not something tied to arrays and hashes. That means that they are also not tied to a particular sigil.

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

This implies that you don't need special dereferencing syntax, and that you can create objects that can act as arrays, hashes and subs at the same time.


[/perl-5-to-6] Permanent link