> it is combining too many new things at once:

Well, it is meant to be the up-front example of everything at once before
the step-by-step...

> * new

These are the heart of construction. I don't think there's any avoiding
that in a class tutorial.

* submethod
> * bless

These are simply necessary components of the above. BUILD is a submethod.
new uses bless. These are non-negotiable aspects of the tutorial.

* named arguments syntax
> * slurping parameter syntax

Named arguments are pretty standard stuff. Slurpy args... I suppose it's
one more thing, but is it really that unusual that we expect someone
reading this not to understand variadic arguments?

> * code golfing cleverness of mapping arguments to identically named named
> arguments

Again, this is how you take arguments to BUILD that set attributes. That's
the correct form, not code golfing.

Constructors in a language that supports a flexible metaobject protocol
aren't trivial beasts.

The real nail in the coffin though is that it's an example that doesn't
> need to use any of those features (nothing about Task really require
> special construction),

This is, I think, the only really significant problem with that example.
The BUILD method is doing no work, and doesn't need to. An example where
new and BUILD were actually required would be vastly more useful.

> * If I have a member that is read-only, when am I allowed to initialize it
> and after what point must already be initialized? Can I assign to it in
> BUILD but not new or vice versa?

You always get a free initializer, so if the user is going to provide it or
it's going to get a static default, you're good to go. But let's say you
have this:

class Foo {
  has $.a;
  has $.b;
  submethod BUILD(:$!a) { $!b = $!a * 10 }

In this case, you need the BUILD submethod because you wanted to have a
dynamic value for the .b attribute that is based on whatever the .a
attribute was set to.

Now, that out of the way, let's make $.b readonly:

  has $.b is readonly;

This doesn't make $.b constant, it merely affects the automatically
generated constructors. So your BUILD routine keeps working. The private
form ($!b) only works within the class, but is not affected by such

* If I want a constructor that takes positional arguments, do I write new
> or BUILD?

For positionals, you have to define a new. Here's another example that does
unecessary work, but in this case to show you what's going on:

$ perl6 foo.p6
new(1, 2) pre-bless
BUILD(1, 2)
$ cat foo.p6
class Foo {
        has $.a;
        has $.b is readonly;
        multi method new($a, $b) {
                say "new($a, $b) pre-bless";
                self.bless(:$a, :$b);
        submethod BUILD(:$!a, :$!b) {
                say "BUILD($!a, $!b)";

my $f = Foo.new(1,2);
say $f.a, $f.b;

> * If I need to do some computation when the object is constructed in order
> to properly initialize the members, do I write new or BUILD? What if one of
> the members I need to initialize is read-only?

All best suited to BUILD.

> * Can either new or BUILD be a multimethod?

Both, sort of. BUILD is a submethod, not a method. It's a sub that looks
like a method. But both can be multi.

> Functions (including operators since they are just functions with a
> different calling syntax after all) normally just operate on their
> arguments without knowing anything about the context with the function was
> called.

This is never a valid assumption in Perl. Perl is all about context. That's
why we have so many operators for enforcing a context (e.g. the prefix ops
?, +, !, so, ~)

> But the pair constructor operator **reaches back magically into the place
> where it was called and changes the argument it was given into a string**

Not really. It's a quoting operator and a binary operator rolled into one.
As such, it's no more strange that it has this "contextual" behavior than
the more traditional quoting operators. You don't balk at the fact that the
doublequotes "reach back" and change the way their parameter is parsed, do
you? In Perl 6, it's just more explicit that quoting operators are actually
operators and can be treated as such.

Reply via email to