Perl6

An Object

class Test {

    method baz {
        say "hi";
    }
}

my $obj = Test.new;
$obj.baz();

Constructors

Unfortunately, the Constructors page in the Perl6 Object Oriented Cookbook is broken. From what I can read in Synopsis 12:

You can write your own BUILD submethod to control initialization. If
you name an attribute as a parameter, that attribute is initialized
directly, so

    submethod BUILD ($.tail, $:legs) {}

is equivalent to

    submethod BUILD ($tail, $legs) {
        $.tail = $tail;
        $:legs = $legs;
    }
Only problem is that Pugs doesn't seem to like BUILD. This code:
class Test {
    submethod BUILD ($.word) {}

    method baz {
        say $.word;
    }
}

my $obj = Test.new("hi");
$obj.baz;
Tells me:
*** Can't use positionals in default new constructor
    at ./test2.p6 line 11, column 12-27
Okay, I think. I'll use a key. Digging through my memory of the p6l mailing list, I try:
class Test {
    submethod BUILD ($.word) {}

    method baz {
        say $.word;
    }
}

my $obj = Test.new(:word("hi"));
$obj.baz;
It works! But now on a hunch, I try:
class Test {
    method baz {
        say $.word;
    }
}

my $obj = Test.new(:word("hi"));
$obj.baz;
Huh. Still works. Okay, now's not the time for questions, so I'll call this good and move on!

Update: I found the following which clarifies: "All classes inherit a default new constructor from Object. It expects all arguments to be named parameters initializing attributes of the same name."

There Goes the Neighborhood

Some favorite features of Perl6:

my $foo;
my $baz = 1;
$foo //= 2;
$baz //= 2;
say $foo;
say $baz;
my $x = 4;
if 2 < $x < 5 { say 'hi'; }

The Mystery of the Missing Defaults

From reading the various Perl6 docs, I get the sense that this should work:

class Test {
    has $.foo = 3;
}
my $obj = Test.new;
say $obj.foo;
But it doesn't.
*** 
    unexpected "{"
    expecting trait, ";" or end of input
    at ./test4.p6 line 3, column 12
I've also seen references to something like this:
class Test {
    has $.foo is :default(3);
}
my $obj = Test.new;
say $obj.foo;
But no dice there either.

Update: I just found a test for this in the repository. I'm going to see if it works. Pasting class Foo2 { has $.bar = "baz"; } into Pugs sure doesn't work.

Heh Heh... You Said MONKEY BUT!

I don't really know why this is called the "monkey but", but that's what Damian called it in his Perl6 talk at OSCON. It's pretty cool though.

sub ($sth) {
    $sth->execute();
    return $sth->fetch_row() but {
         $sth->finish();
    };
} 
I'm a little frustrated by the required ';' after the block. =\

Do Be Do Be Do!

Unlike Perl5, the contents of { } blocks are not evaluated. Instead, in Perl6, { 4 + 5 } defines an anonymous subroutine. I believe the symantics are identical to sub { 4 + 5 }, which is also a supported form in Perl6.

In order to get code evaluated in a new context, you know use a "do".

my $foo = do { 4 + 5 };

What for?

I still remember the look in a certain C programmer's eyes when I introduced him to Perl5's 'foreach' loop. I've since been won over by collection closure methods (iteration methods that take functions as parameters, ala Smalltalk or Ruby's blocks). But the 'foreach' loop is still good stuff.

In Perl6, 'foreach' is spelled 'for'. And it looks a little different.

my @array = (1, 2, 3);
for @array -> $item {
    say $item;
}
Perl5 programmers might be freaking out here. I remember thinking, uh, that's different. Yup.

Okay, digression time. So far we've seen that you can declare anonymous subs these to ways:

my $anon_sub1 = sub ($word) { say $word };
my $anon_sub2 = { say "I don't think this form can have parameters" };
Well, there's another way. They're called "pointy subs". These vampiric functions look a little like this...
my $sub_three = -> $word { say $word };
Yeah, okay, that looks a little weird, but now think about it in the context of that for loop.
my @array = (1, 2, 3);
for @array -> $item {
    say $item;
}
The Perl6 for loop is a collection closure function. Whoa. Good stuff. Unfortunately, pugs is a little picky about for loops. Let's digress.

Here's a function that takes a parameter and a function as parameters, then calls the function with the parameter. Below it are some ways to invoke it.

sub doit ($param, $func) {
    $func($param);
}

my $sayit = sub ($word) { say $word };
doit("badger", $sayit);

doit("badger", sub ($word) { say $word });

doit("badger", { say $_ });

doit("badger", &say);
The first three invokations work, the last one is a no go, though I'm not really sure why. It seems to me that should pass it the "say" function we've been using all along, but there must be some weirdness. Anyways, the second and third invokation have that horrible });. Ladies and gentlemen, I heard it from Matz's mouth. }); makes Matz sad. And you wouldn't want to make the Matz sad, would you? That's why he created this special syntax for passing a single block. And it's a really good syntax (warning! Ruby code ahead!):
obj.meth(param) {
    we.are(in, a, codeblock, now)
}
Of course, every once in a while this really pisses me off, because what if I want to pass two code blocks? Well, the shit hits the fan and you have to change syntax to pass the other one, and they have to be handled differently on the receiving end. Ugh.

Seems like Perl6 has a pretty good answer for this, and it's "pointy subs". What's that you say?

doit("badger", -> $word { say $word });
Hardly looks better? Well, you're right. But how about this:
doit "badger" -> $word { say $word };
doit "badger" -> $word {
    say $word;
}
Looks pretty good, eh? Only problem is: it doesn't work in pugs yet. That said, I think this is great, because not only is it a nice short lambda syntax, the arrow suggests a flowing forward that makes passing multiple anonymous functions into another function look pretty logical.

But I Want RUBY!

Me too man, me too. But I also really want Perl6. So have a look at this official and very real Perl6 code:

my @list = (1, 2, 3);
say @list.map:{ $_ + 1 };
I'm not even kidding! Bam! Now, the question remains, will Perl6 have all the wonderful methods we've come to know and love in the Ruby Core classes? I sure hope so, and I might even be willing to write some code if I have to (to make sure). But thankfully, this stuff can be added 3rd party pretty easily.