Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is that one argument or none for a Perl 6 block?

What is the Perl 6 way to tell the difference between an argument and no argument in a block with no explicit signature? I don't have any practical use for this, but I'm curious.

A block with no explicit signature puts the value into $_:

my &block := { put "The argument was $_" };

The signature is actually ;; $_? is raw. That's one optional argument. The @_ variable isn't defined in the block because there is no explicit signature.

There's the no argument, where $_ will be undefined:

&block();  # no argument

But there's also a one argument situation where $_ will be undefined. A type object is always undefined:

&block(Int);

But, an $_ with nothing in it is actually an Any (rather than, say, Nil). I can't tell the difference between these two cases:

&block();
&block(Any);

Here's a longer example:

my $block := {
    say "\t.perl is {$_.perl}";

    if $_ ~~ Nil {
        put "\tArgument is Nil"
        }
    elsif ! .defined and $_.^name eq 'Any' {
        put "\tArgument is an Any type object"
        }
    elsif $_ ~~ Any {
        put "\tArgument is {$_.^name} type object"
        }
    else {
        put "\tArgument is $_";
        }
    };

put "No argument: ";    $block();
put "Empty argument: "; $block(Empty);
put "Nil argument: ";   $block(Nil);
put "Any argument: ";   $block(Any);
put "Int argument: ";   $block(Int);

Notice the no argument and Any argument forms show the same things:

No argument:
    .perl is Any
    Argument is an Any type object
Empty argument:
    .perl is Empty
    Argument is Slip type object
Nil argument:
    .perl is Nil
    Argument is Nil
Any argument:
    .perl is Any
    Argument is an Any type object
Int argument:
    .perl is Int
    Argument is Int type object
like image 343
brian d foy Avatar asked Aug 01 '17 02:08

brian d foy


1 Answers

As far as I know, the only way to know the number of parameters passed without an explicit signature, is to use @_ inside the body, which will generate a :(*@_) signature.

my &block := { say "Got @_.elems() parameter(s)" };
block;               # Got 0 parameter(s)
block 42;            # Got 1 parameter(s)
dd block.signature;  # :(*@_)

Yeah, the good old @_ is still there, if you want it :-)

like image 128
Elizabeth Mattijsen Avatar answered Sep 28 '22 10:09

Elizabeth Mattijsen