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”