🔬27. Obsolete syntax error messages in Perl 6, part 4

🔬27. Obsolete syntax error messages in Raku, part 4

N. B. Perl 6 has been renamed to Raku. Click to read more.


So far, we covered a lot of different error messages that Rakudo Perl 6 generates when you accidentally use the Perl 5 syntax. This is a really nice feature for easy migration to the new language.

Let us continue and cover another couple of errors.

new X

It was one of the hottest topics in Perl 5 to forbid indirect method calls. Personally, I always preferred to use an arrow for method calls while still feeling better with new X(...) when creating objects. Now, Perl 6 prevents that and it looks like it knows something about my first language:

$ perl6 -e'say new Int;'
===SORRY!=== Error while compiling -e
Unsupported use of C++ constructor syntax;
in Perl 6 please use method call syntax
at -e:1
------> say new Int⏏;

The attempt to use a C++ constructor call is blocked by the following rule in the Grammar:

token term:sym<new> {
    'new' \h+ <longname> \h* <![:]>
    <.obs("C++ constructor syntax", "method call syntax")>
}

It allows the following code, though:

my $c = new Int:;
$c++;
say $c; # 1

-> vs .

Another aspect of object-oriented programming is the way methods are called. In Perl 5, it used to be an arrow while in Perl 6 methods are called with a dot.

So, neither $x->meth nor $x->() should work. The rules that catch that are defined as the following:

# TODO: report the correct bracket in error message
token postfix:sym«->» {
    <sym>
    [
    | ['[' | '{' | '(' ] <.obs('->(), ->{} or ->[] as postfix dereferencer', '.(), .[] or .{} to deref, or whitespace to delimit a pointy block')>
    | <.obs('-> as postfix', 'either . to call a method, or whitespace to delimit a pointy block')>
    ]
}

The token extracts an arrow and prints one of the two messages depending on the next character.

If the character is an opening brace, it would be nice to make a less generic message, and the TODO comment actually agrees that it is the desired thing. Let us try making that at home.

method bracket_pair($s) {
    $s eq '{' ?? '}' !! $s eq '[' ?? ']' !! ')'
}

token postfix:sym«->» {
    <sym>
    [
    | $<openingbracket>=['[' | '{' | '(' ] {
        my $pair := $<openingbracket> ~ self.bracket_pair(~$<openingbracket>);
        self.obs("->$pair as postfix dereferencer",
                 ".$pair to deref, or whitespace to delimit a pointy block")
    }
    | <.obs('-> as postfix', 'either . to call a method, or whitespace to delimit a pointy block')>
    ]
}

The changes are shown in bold. First, I save the opening brace in $<openingbracket>, then, a simple function finds its matching pair, and finally, the $pair variable gets both parts, so either {}, or [], or ().

The goal has been achieved:

$ ./perl6 -e'say Int->{}'
===SORRY!=== Error while compiling -e
Unsupported use of ->{} as postfix dereferencer;
in Perl 6 please use .{} to deref, or whitespace
to delimit a pointy block
at -e:1
------> say Int->⏏{}
    expecting any of:
        postfix

Maybe it also worth not mentioning pointy blocks for [] and ().

As homework, try using the method that Rakudo is using itself for detecting the closing bracket-pair instead of our function above.

One thought on “🔬27. Obsolete syntax error messages in Perl 6, part 4”

Leave a Reply

Your email address will not be published. Required fields are marked *

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code