Perl6-Doc

 view release on metacpan or  search on metacpan

share/Synopsis/S12-objects.pod  view on Meta::CPAN


    .doit: 1,2,3        # okay, three arguments
    .doit(1): 2,3       # okay, one argument plus list
    .doit (): 1,2,3     # ILLEGAL (two terms in a row)

In particular, this allows us to pass a final closure in addition to the
"normal" arguments:

    .doit: { $^a <=> $^b }              # okay
    .doit(): { $^a <=> $^b }            # okay
    .doit(1,2,3): { $^a <=> $^b }       # okay

Normally a space is required after the colon to disambiguate what
follows from a pair that extends the previous name.  However,
names may not be extended with the C<:{}> pair notation, and therefore
it is allowed to drop the space after the colon if the first argument
to the method is a closure.  Hence, any of the above may be written
without the space after the colon:

    .doit:{ $^a <=> $^b }              # okay
    .doit():{ $^a <=> $^b }            # okay
    .doit(1,2,3):{ $^a <=> $^b }       # okay

These are parsed as there were a space there, so the argument list may
continue if the closure is followed by a comma.

In case of ambiguity between indirect object notation and dot form,
the nearest thing wins:

    dothis $obj.dothat: 1,2,3

means

    dothis ($obj.dothat(1,2,3))

and you must say

    dothis ($obj.dothat): 1,2,3

or

    $obj.dothat.dothis: 1,2,3

if you mean the other thing.

Also note that if any term in a list is a bare closure or pointy
sub, it will be considered to be the final argument of its list
unless the closure's right curly is followed immediately by comma
or colon.  In particular, a method call does *not* extend
the list, so you can say:

    @list.grep: { $_ % 2 }.map: { $_ - 1 }.say

and that will be taken as equivalent to

    @list.grep({ $_ % 2 }).map({ $_ - 1 }).say

Since the colon does not require a space in this case, and it looks
slightly odd there anyway, it may be clearer to omit the space to make
the method calls on the right look more like they attach to the term
on the left in one cascade of method calls:

    @list.grep:{ $_ % 2 }.map:{ $_ - 1 }.say

Methods (and subs) may be declared as lvalues with C<is rw>.  You can
use an argumentless C<rw> method anywhere you can use a variable,
including in C<temp> and C<let> statements.  (In fact, you can use an
C<rw> method with arguments as a variable as long as the arguments are
used only to identify the actual value to change, and don't otherwise
have strange side effects that differ between rvalue and lvalue usage.
Setter methods that expect the new value as an argument do not fall
into the well-behaved category, however.)

Method calls on mutable scalars always go to the object contained in
the scalar (autoboxing value types as necessary):

    $result = $object.doit();
    $length = "mystring".codes;

Method calls on non-scalar variables just calls the C<Array>, C<Hash>
or C<Code> object bound to the variable:

    $elems = @array.elems;
    @keys  = %hash.keys;
    $sig   = &sub.signature;

Use the prefix C<VAR> macro on a scalar variable to get at its
underlying C<Scalar> object:

    if VAR($scalar).readonly {...}

C<VAR> is a no-op on a non-scalar variables and values:

    VAR(1);     # 1
    VAR(@x);    # @x

There's also a corresponding C<< postfix:<.VAR> >> macro that can be used
as if it were a method:

    if $scalar.VAR.readonly {...}

(But since it's a macro, C<VAR> is not dispatched as a real method.
To dispatch to a real C<.VAR> method, use the indirect C<$obj."VAR">
form.)

You can also get at the container through the appropriate symbol table:

    if MY::<$scalar>.readonly {...}

=head1 Class methods

Other OO languages give you the ability to declare "class" methods that
either don't need or actively prohibit calls on instances.  Perl 6 gives
you a choice.  If you declare an ordinary method, it can function as a
"class" method when you pass it a type object such as "C<Dog>" regardless
of how defined the prototype object is, as long as the method body doesn't
try to access any information that is undefined in the current instance.

Alternately, you can associate a method with the current metaclass instance,
which as a singleton object knows your package, and can function as a
more traditional "class" method:



( run in 1.751 second using v1.01-cache-2.11-cpan-39bf76dae61 )