Perl の syntax check

Perl の syntax check って subroutine の存在チェックをどこまでしてくれるんだろうと思って調べてみた。(Perl 5.8.7 on FreeBSD-5.4)

#!/usr/local/bin/perl

use strict;
use warnings;

not_exist();

# typo サブルーチン
sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
test.pl syntax OK

チェック OK

#!/usr/local/bin/perl

use strict;
use warnings;

not_exist;

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
Bareword "not_exist" not allowed while "strict subs" in use

Bareword なので NG

#!/usr/local/bin/perl

use strict;
use warnings;

if (0) {
    not_exist;
}

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
test.pl syntax OK

チェック OK

#!/usr/local/bin/perl

use strict;
use warnings;

my $a = 0;
if ($a) {
    not_exist;
}

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
Bareword "not_exist" not allowed while "strict subs" in use

Bareword again

#!/usr/local/bin/perl

use strict;
use warnings;

use constant A => 0;
if ( A ) {
    not_exist;
}

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
syntax OK

constant を使うと OK

#!/usr/local/bin/perl

use strict;
use warnings;

use constant A => 1;
if ( A ) {
    not_exist;
}

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
Bareword "not_exist" not allowed while "strict subs" in use

constant を真の値にすると NG

#!/usr/local/bin/perl

use strict;
use warnings;

sub A { 0 }
if ( A ) {
    not_exist;
}

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
Bareword "not_exist" not allowed while "strict subs" in use

constant の代わりに sub を書くとその結果が偽でも NG

#!/usr/local/bin/perl

use strict;
use warnings;

sub exist {
    not_exist;
}

exist;

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
Bareword "not_exist" not allowed while "strict subs" in use

subroutine のなかに書いても NG

#!/usr/local/bin/perl

use strict;
use warnings;

sub exist {
    not_exist();
}

exist;

sub not_exit {
    print "hoge\n";
}
% perl -wc test.pl
syntax OK

存在する subroutine 内の存在しない subroutine が Bareword でなければ OK

"strict subs" に Bareword と判定されるか否かでエラーが出力されてるので、subroutine の存在チェックというものは基本的にないのか。

constant を使うのと my を使うのとで差が出るのはコンパイル時チェックと実行時チェックの違いなんだろうな。use constant A => 0; と sub A { 0 } の違いもいっしょかな?これって全く一緒の挙動をするかと思ってたけど。

Bareword を絶対通らない箇所に書いても問題ないのはそういう仕様なのか?

#!/usr/local/bin/perl

use strict;
use warnings;

if (0) {
    Does this will be syntax error "?"
}
% perl -wc test.pl
syntax OK

そういう仕様みたいだなぁ。

#!/usr/local/bin/perl

use strict;
use warnings;

if (0) {
    This is absolutely syntax error !!
}
% perl -wc test.pl
syntax error at no_exist_subroutine.pl line 7, near "error !"

明らかな構文エラーはさすがに補足されるか。

わからないこと多し。