strict.pm

vars.pm は変数名を導入するためのモジュールですが、Perl では C のように変数を宣言する必要がないので必要性がもうひとつはっきりしません。実は、vars.pm は変数名やリファレンス、サブルーチン名をチェックする strict.pm と関係しているようです。use strict; が宣言されていると、変数がmy で宣言したプライベート変数か、パッケージ名を含めて完全に記述された変数しか使えなくなります。不正な変数名の使用によるクラッシュを避けるためです。例えば次の Sample.pm モジュールと test_sample.pl スクリプト本体からなるプログラムを作ります。

package Sample;
sub import {
$main::hello = 'hello';
}
1;
# Sample.pm
use Sample;
# use strict;
print $hello, "\n";
# test_sample.pl

use strict をコメントアウトしたままで test_sample.pl を走らせると一応動作します。

$ perl test_sample.pl
hello

こんどは、次のように use strict; のコメントを外してテストします。

use Sample;
use strict;
print $hello, "\n";
# test_sample.pl

すると、次のようなエラーメッセージがでてプログラムは動作しません。

$ perl test_sample.pl 
Variable "$hello" is not imported at test_sample.pl line 3.
Global symbol "hello" requires explicit package name at test_sample.pl line 3.
Execution of test_sample.pl aborted due to compilation errors.

ここで use vars qw( $hello ); を導入して $hello をインポートします。

use Sample;
use strict;
use vars qw( $hello );
print $hello, "\n";
# test_sample.pl

今度は動作しました。

$ perl test_sample.pl
hello

strict.pm のようにコンパイルに影響をあたえるモジュールを pragmatic module といいます。strict.pm の使いかたは、perldoc strict で見ることができます。use strict "vars"; で変数の使用法が厳格にチェックされます。use strict; では変数名、サブルーチン、リファレンスの全てでチェックが厳格になります。strict.pm の本体は次のような短いスクリプトです。

sub bits {
    my $bits = 0;
    my $sememe;
    foreach $sememe (@_) {
        $bits |= 0x00000002, next if $sememe eq 'refs';
        $bits |= 0x00000200, next if $sememe eq 'subs';
        $bits |= 0x00000400, next if $sememe eq 'vars';
    }
    $bits;
}

sub import {
    shift;
    $^H |= bits(@_ ? @_ : qw(refs subs vars));
}

sub unimport {
    shift;
    $^H &= ~ bits(@_ ? @_ : qw(refs subs vars));
}

1;

sub bits は引数が'refs'、'subs'、'vars' のときは $bits の対応するビットを 1 にします。import は bits で作成した $bits と $^H の値の OR をとって'refs'、'subs'、'vars' に対応するビットを 1 にします。$^H の内容は Perl のコンパイルの動作に影響します。unimport は import とは逆に対応するビットを 0 にします。また、unimport 関数は no strict; で呼び出されます。

strict.pm と同じ pragmatic module に integer.pm があります。use integer; と記述するとそのブロックでは、コンパイル時に整数演算のライブラリーを使います。no integer; とすると、浮動小数点演算用のライブラリーで計算されます。integer.pm のソースも strict.pm と一緒で、下記のように$^Hのビットの on-off をするだけです。

sub import {
    $^H |= 1;
}

sub unimport {
    $^H &= ~1;
}

1;