Author Archive

Day 24 — Subs are Always Better in multi-ples

December 24, 2011

Hey look, it’s Christmas Eve! (Also, the palindrome of 42!) And today, we’re going to learn about multi subs, which are essentially synonyms (like any natural language would have). Let’s get started!

An Informative Introduction

multi subs are simply subroutines (or anything related to it, such as methods, macros, etc.) that start with the multi keyword and are then allowed to have the same name as another sub before, provided that sub starts with a multi (or proto — that’s later) keyword. What has to be different between these subs is their signature, or list of formal parameters.

Sound complicated? It isn’t, just take a look at the example below:

multi sub steve(Str $name) {
    return "Hello, $name";
}

multi sub steve(Int $number) {
    return "You are person number $number to use this sub!";
}

Every sub was started with the multi keyword, and has the same name of “steve”, but its parameters are different. That’s how Perl 6 knows which steve to use. If I were to later type steve("John"), then the first steve gets called. If, however, I were to type steve(35), then I’d get the second steve sub.

Equal Footing with built-ins

When you write a multi sub, and it happens to have the same name as some other built-in, your sub is on equal footing with the compiler’s. There’s no preferring Perl 6′s multi sub over yours, so if you write a multi sub with the same name as a built-in and with the same signature, say

multi sub slurp($filename) {
    say "Yum! $filename was tasty. Got another one?";
}

And then try calling it with something like slurp("/etc/passwd"), I get this:

Ambiguous dispatch to multi 'slurp'. Ambiguous candidates had signatures:
:(Any $filename)
:(Any $filename)

Why? Because Perl 6 found two equally valid choices for slurp("/etc/passwd"), my sub and its own, and was unable to decide. That’s the easiest way I know to demonstrate equal footing.

A Fun Conclusion

Now, since it’s Christmas, let’s try writing another open sub, but unlike the built-in open sub, which opens files, this one open presents! Here’s our Present class for this example:

class Present {
    has $.item;
    has $.iswrapped = True;

    method look() {
        if $.iswrapped {
            say "It's wrapped.";
        }
        else {
            say $.item;
        }
    }

    method unwrap() {
        $!iswrapped = False;
    }
}

Now, our open multi sub looks like this:

multi sub open(Present $present) {
    $present.unwrap;
    say "You unwrap the present and find...!";
}

The signature is vastly different from Perl 6′s own open sub, which is a good thing. And here’s the rest of the code, which makes a Present and uses our new multi sub:

my $gift = Present.new(:item("sock"));
$gift.look;
open($gift);
$gift.look;

But wait!

Running this gets us an error in the latest pull of Rakudo:

$ ./perl6 present.p6
It's wrapped.
This type cannot unbox to a native string
⋮

This means that Perl 6′s original open sub is being used, so perhaps it’s being interpreted as an only sub (only subs are the default — only sub unique() {...} and sub unique() {...} mean the same thing). No matter, let’s try adding a proto sub line before our multi sub:

proto sub open(|$) {*}

A proto sub allows you to specify the commonalities between multi subs of the same name. In this case, |$ means “every possible argument”, and {*} means “any kind of code”. It also turns any sub with that name into a multi sub (unless explicitly defined as something other than multi). This is useful if you’re, say, importing a &color sub from a module that isn’t defined as multi (or explicitly as only) and you want to have your own &color sub as well.

After adding this before our multi sub open, we get this result:

$ ./perl6 present.p6
It's wrapped.
You unwrap the present and find...!
sock

It works! Well, that’s it for multi subs. For all the nitty-gritty details, see the most current S06. Enjoy your multi subs and your Christmas Eve!

Day 16: Time in Perl6

December 16, 2010

It’s the 0x10th day of Christmas, and it’s time for you to learn of time. The synopsis S32::Temporal has been heavily revised in the past year, and today’s post details some of the basics of time as it is implemented in Perl 6.

time and now

The two terms that give the current time (at least what your system thinks is the current time) are time; and now. Here’s a quick example:
> say time; say now;
1292460064
Instant:2010-12-16T00:41:4.873248Z

The first (obvious) difference is that time returns POSIX time, as an integer. now returns an object known as an Instant. Use now if  you want fractions of a second and recognition of leap seconds. time won’t give you fractions of a second or leap seconds, because it returns POSIX time. Which one you use all depends on what you need.

DateTime and friend

Most of the time, you will want to store dates other than now. For this, the DateTime object is what you need. If you want to store the current time, you can use:

my $moment = DateTime.new(now); # or DateTime.new(time)

Otherwise, there are two ways of creating a DateTime object:

my $dw = DateTime.new(:year(1963), :month(11), :day(23), :hour(17), :minute(15));

This is in UTC, if you want to enter it in in another timezone, use the :timezone adverb. Here, only :year is required, the rest defaults to midnight on January 1 of the year.

This way is also pretty tedious. You could instead create a DateTime object by inputting an ISO 8601 timestamp, as a string.

my $dw = DateTime.new("1963-11-23T17:15:00Z");

The Z denotes UTC. To change that, replace Z with +hhmm or -hhmm, where ‘hh’ is the number of hours offset and ‘mm’ the number of minutes.

There is also a Date object, which is created in a similar way, but without hours, minutes, or seconds. For example:

my $jfk = Date.new("1963-11-22"); # you can also use :year and so on

The introduction of the Date object is actually a lesson from CPAN’s DateTime module: sometimes you want to treat days without having to worry about things like time zones and leap seconds. It’s inherently easier to handle pure dates. For example Date has built-in .succ and .pred methods, so you can increment and decrement them in your code.

$jfk++; # Day after JFK

Finally…

That’s about it for Time in P6. To see all the gritty details go to the Temporal specification or ask about it in the community!

Day 13 – The Perl6 Community

December 13, 2010

Today is the halfway point of the Perl 6 Advent Calendar (and indeed any advent calendar). For 12 days you have learned various nuggets of information, and most likely experimented with those various bits of knowledge. You feel great, wonderful, stuff works!

And then it didn’t work.

You may have found your way to some documentation (available at http://perl6.org/documentation by the way), and potentially even some talk of Real People™ out there ready to help you. Whatever you’ve done, today’s post is given to you to display the two main methods of helping in the Perl 6 Universe.

The Mailing Lists

The first of two major communication channels is the mailing lists. If you head on over to http://perl6.org/community, you can see on the right hand side a list of the several lists you can subscribe to/peruse the archives of. If you have question s about the language, such as “How do I add up all the numers in an array without a loop?”, go for perl6-users. The mailing list is great for those who can’t use IRC or want more permanent discussions. Have an idea for the language? Try perl6-language, where people discuss the language itself. Things like “I think there should be a beat-object-with-catfish operator in the language” go here.

Now, the mailing lists aren’t the only option. Your question could be simple-when-you-know-it, or maybe that feature you really really want is already there! For these reasons, you may want to run your comments by the IRC community.

The #perl6 IRC channel

If you want to use something more instantaneous instead, or you hate the idea of signing up to a mailing list for one question, head over to the channel #perl6 on irc.freenode.net. Here, the community is reputed as being one of the nicest on the Internet (so if you’ve been burned by IRC channels before and vowed “Never again shall I use IRC!”, try #perl6.)

#perl6 is like an eccentric incarnation of The Doctor, multifaceted in its nature. We have punfests, technotalk, lolz, above-your-head language design, and more (thanks sorear for reminding me of that)! So come and ask away!

Final Words

These are the two ways of communication in the Perl 6 universe. There are also blogs, screencasts, and more. Go to http://perl6.org to check it all out!


Follow

Get every new post delivered to your Inbox.

Join 25 other followers