TOP > スクリプト制作メモ > use と require

≫use と require

Perl で外部ライブラリなりモジュールなりをロードする命令には、use と require の2つがある。

使い分けはどうすれば良いのか。

まず、大前提が2つ。
use は Perl5以上でないと使えない
require はバージョンを問わず使える
use はコンパイル時に評価される
require は実行時に評価される

≫評価されるタイミングの違い

use は、実行時最初に読み込まれるので、スクリプトのどこに書いても、全て最初(コンパイル時)にメモリにロードされます。

require はスクリプトの実行時に逐次呼ばれるので、必要なときだけメモリにロードするという制御が可能です。

例えば、
if($str eq 'ok'){
    require 'ExampleRequire.pm';
    use ExampleUse;
}
この場合、ExampleRequire.pm は、$str が ok の場合にロードされます。

対して、ExampleUse は、$str の値に関わらず、スクリプトがコンパイルされるとともにメモリにロードされます。

したがって、
例えば、実行する可能性の低いルーチンをライブラリ化して、必要なときのみ require すれば、スクリプト全体の起動オーバーヘッドを軽減できます。

また、
サーバで常駐したり、子プロセスを fork するようなスクリプトを実行する場合は、モジュールを use することでメモリ使用率を軽減することができるのです。

≫BEGIN, CHECK, INIT ルーチン

use されるモジュールの中では、BEGIN, CHECK, INIT ルーチンが実行できます。

BEGIN, CHECK, INIT ルーチンがどういうものかは、以下のコードを参考にしてください。
#!/usr/bin/perl
# メインルーチン
print "メインルーチンでの出力\n";
exit;
# BEGIN, CHECK, INIT ルーチン
BEGIN {
    print "BEGINでの出力\n";
}
CHECK {
    print "CHECKでの出力\n";
}
INIT {
    print "INITでの出力\n";
}
実行結果は、
BEGINでの出力
CHECKでの出力
INITでの出力
メインルーチンでの出力
となります。

BEGIN, CHECK, INIT ルーチンは、sub を省略して書くことが出来る特殊なサブルーチンです。

BEGIN, CHECK, INIT ルーチンは、メインルーチンよりも先に、コールされなくても実行されます。

この、特殊な BEGIN, CHECK, INIT ルーチンが use されるモジュール内にあった場合、コンパイルされた後に、メインルーチンより先に実行されます。

require では、ロードすると同時に、ライブラリ内の BEGIN ルーチンだけが実行できます。

以下の BeCheIn.pm でテストします。

[BeCheIn.pm]
package BeCheIn;
use strict;
INIT { print "INITの出力\n" }
BEGIN { print "BEGINの出力\n" }
CHECK { print "CHECKの出力\n" }
sub hoge { print "hogeの出力\n" }
1;
BeCheIn.pm を require して実行するメインルーチン。
#!/usr/bin/perl
print "メインルーチンの出力\n";
require 'BeCheIn.pm';
BeCheIn::hoge();
実行結果は、
メインルーチンの出力
BEGINの出力
hogeの出力
となります。

プログラミングの並び順で実行され、BEGIN ルーチンは、require された時点で、実行されています。
また、CHECK, INIT ルーチンは実行されません。

次に、use して実行するメインルーチン。
#!/usr/bin/perl
print "メインルーチンの出力\n";
use BeCheIn;
BeCheIn::hoge();
実行結果は、
BEGINの出力
CHECKの出力
INITの出力
メインルーチンの出力
hogeの出力
となります。

メインルーチンが実行される前に use するモジュール BeCheIn.pm の BEGIN, CHECK, INIT ルーチンが実行されています。

≫Exporter モジュールによる関数のインポート

use は、Exporter モジュールによる関数の自動インポートが可能ですが、require では、不可能です。

以下のようなライブラリを考えます。

[ Exptr.pm ]
package Exptr;
use base Exporter;
use strict;
our @EXPORT_OK = qw(hoge);
sub hoge { print "hogeの出力\n" }
1;
use で実行するメインルーチン
#!/usr/bin/perl
use Exptr qw(hoge);
hoge();
実行結果は、
hogeの出力
正常に print が実行されます。

では、require するメインルーチンの場合。
#!/usr/bin/perl
require 'Exptr.pm';
hoge();
実行してみると、
Undefined subroutine &main::hoge called at ./xxxxx.xxx line X.
hoge が定義されていないとのエラーになってしまいます。

require の場合は、自動実行することはできませんが、手動で use と同様の振る舞いを実現できます。
BEGIN {
    require MODULE;
    MODULE->import(LIST);
}

ってな感じで、いろいろ調べてみると、上記のような違いがあるようです。


TOP > スクリプト制作メモ > use と require
(C) bayashi.net