Yves 在 perl-5.37.4 (開發版)中提供了一項很不錯的更新:
取自:
https://metacpan.org/release/ETHER/perl-5.37.4/changes
Syntax errors will no longer produce "phantom error messages".
Generally perl will continue parsing the source code even after
encountering a compile error. In many cases this is helpful, for
instance with misspelled variable names it is helpful to show as many
examples of the error as possible. But in the case of syntax errors
continuing often produces bizarre error messages, and may even cause
segmentation faults during the compile process. In this release the
compiler will halt at the first syntax error encountered. This means
that any code expecting to see the specific error messages we used to
produce will be broken. The error that is emitted will be one of the
diagnostics that used to be produced, but in some cases some messages
that used to be produced will no longer be displayed.
也就是以後在編譯時期,若發現語法錯誤,就會立刻停止。這代表:語法錯誤訊息會更加簡化。
相關的公告跟 PR 在:
-
https://www.nntp.perl.org/group/perl.perl5.porters/2022/09/msg264716.html
-
https://github.com/Perl/perl5/pull/20168
寫了個就簡單的範例,用 macOS 內附的 perl5.18 、perl5.30 及用 perlbrew 裝的 perl5.37.4
來比較了一下,可以看到在語法錯誤「連續出現」時, perl5.37.4 只會報第一個錯誤,然後就停止了。
這個行為其實很合理,畢竟其實只要錯一個字符,就該讓整段程式碼變成無法編譯。
目前為止 perl 會在看到語法錯誤時繼續編譯,並試著列舉出整段程式碼中所有
有語法錯誤的地方。雖然有時候是對的,但多數時候實際上的錯誤都會比錯誤訊
息中提供的位置還要更前面一點。以下的錯誤訊息都將第一個錯誤報在第 6 行,
但實際上或許該算在第 5 行比較合理,畢竟改修正的地方就是在第 5 行。
但畢竟,編譯器是無法決定「正確的」修正該在哪裡的,程式設計師才能。
----8<----
# bat --style numbers
err.pl
1 use strict;
2 use warnings;
3
4 sub foobar {
5 my $bar = 41
6 my $bas = 42
7 my $bat = 43;
8
9 my $bau = 44
10 my $bav = 45;
11
12 say $bar;
13 }
# /usr/bin/perl5.18 -c
err.pl
syntax error at
err.pl line 6, near "my "
Global symbol "$bas" requires explicit package name at
err.pl line 6.
syntax error at
err.pl line 10, near "my "
Global symbol "$bav" requires explicit package name at
err.pl line 10.
Global symbol "$bar" requires explicit package name at
err.pl line 12.
err.pl had compilation errors.
# /usr/bin/perl5.30 -c
err.pl
syntax error at
err.pl line 6, near "my "
Global symbol "$bas" requires explicit package name (did you forget to declare "my $bas"?) at
err.pl line 6.
Can't redeclare "my" in "my" at
err.pl line 9, near "my"
syntax error at
err.pl line 10, near "my "
Global symbol "$bav" requires explicit package name (did you forget to declare "my $bav"?) at
err.pl line 10.
Global symbol "$bar" requires explicit package name (did you forget to declare "my $bar"?) at
err.pl line 12.
err.pl had compilation errors.
# perl5.37.4 -c
err.pl
syntax error at
err.pl line 6, near "my "
err.pl had compilation errors.
---->8----