BEGINブロック、CHECKブロック、INITブロック、ENDブロック
Perlプログラムが実行されるまでの流れは下記のようになります。
この流れの中で自動実行されるブロックがあります。
実行されるブロックとその実行タイミングは以下のようなものです。
- INITブロック
- コンパイルフェイズで実行されるブロック
- CHECKブロック
- コンパイルフェイズが終了した時に実行されるブロック
- INITブロック
- インタプリタフェイズに入る前に実行されるブロック
- ENDブロック
- インタプリタフェイズが終了した後に実行されるブロック
これが本当かどうかを、確認用のプログラムで確かめてみます。
use strict; use warnings; print "start main running here\n"; die "main now dying here\n"; die "XXX: not reached\n"; END { print "END: done running\n" } CHECK { print "CHECK: done compiling\n" } INIT { print "INIT: started running\n" } BEGIN { print "BEGIN: still compiling\n" }
まずこのプログラムを「perl -c」コマンドに読み込ませてみます。
このコマンドは、コンパイルだけ行ない実行はしません。
ということなので、コンパイルフェイズで実行されるものだけが実行されることになります。
表示結果は下記のようになりました。
BEGIN: still compiling CHECK: done compiling
BEGINブロックとCHECKブロックのみが実行されていますね。
次に「perl」コマンドに読み込ませます。
今度はプログラムが実行されます。
表示結果は下記のようになりました。
BEGIN: still compiling CHECK: done compiling INIT: started running start main running here main now dying here END: done running
コンパイルフェイズで実行されるBEGINブロック,CHECKブロックが実行され、
インタプリタフェイズ開始で実行されるINITブロックが実行され、
print関数、die関数が実行され、
プログラムが終了してENDブロックが実行されました。
requireとuseの違いについて
モジュール読み込み関数として「require」と「use」があります。
両者の違いはどこにあるかというと、読み込むタイミングにあります。
require関数は、実行処理の流れで呼び出されるまで、モジュールを読み込みません。
use関数は、コンパイルフェイズでモジュールを読み込みます。
例えば「use MyTest」は、下記のプログラムと同等の意味を持っています。
BEGIN { require MyTest; MyText::import; }
試しにMyTest.pmを作成して読み込んでみます。
package MyTest; use strict; use warnings; sub import { print "Imported\n" } 1;
このモジュールをuseで読み込んでいるプログラムを「perl -c」で実行すると「Imported」と表示されます。