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”