windyakinってなんて読む

うぃんぢゃきんではない

requireでuseのqwを使う方法 と モジュールが存在しなかった時に例外処理をさせる方法

昨日知ったことのまとめ

useの場合

まず普通にuseするときはこんな感じ(例:Digest::SHA1)

use Digest::SHA1 qw(sha1_base64);
$trip = substr(sha1_base64($key), 0, 12);

requireの場合

requireの場合以下のようにqwはできません。

# This is bad code!!!(英語合ってる?)
require Digest::SHA1 qw(sha1_base64);

仕方ないので以下のように書きます。

require Digest::SHA1;
Digest::SHA1->import( qw(sha1_base64) );
$trip = substr(sha1_base64($key), 0, 12);

このコードはuseの場合とほぼ同じ動き*1をします。

requireを使ってuseと全く同じ動きをしたい場合

以下のようにすればuseした時と同じようにrequireを使うことができます*2
モジュール読み込み部分をBEGINブロックで囲みます。

BEGIN {
	require Digest::SHA1;
	Digest::SHA1->import( qw(sha1_base64) );
}
$trip = substr(sha1_base64($key), 0, 12);

モジュールが存在しなかった時に例外処理をさせる

Digest::SHA1Perlのバージョンなどによって標準で入ってなかったりしても、大体は「use lib」とかBEGINブロックで@INCにpushすれば動いてくれるはず。…それでも@pagesの一部サーバー*3では読み込めないとかいう謎の事態に陥った。
evalを使って無理やり実行させた後、エラーっぽかったら例外処理をさせておきます。

eval {
	require Digest::SHA1;
	Digest::SHA1->import( qw(sha1_base64) );
	$trip = substr(sha1_base64($key), 0, 12);
};
if ( $@ ) {
	# エラーの時の処理
	$trip = "???(e)";
}

まぁこのコードはあまりよくないと思うので、あくまで応急処置として使いましょう。

とまぁこんな感じで一応ぜろちゃんねるプラスがDigest::SHA1をどうしても読み込めない困ったサーバーでも使えるようになりましたとさ。めでたしめでたし。

*1:読み込むタイミングがuseはコンパイル時なのに対して、requireは実行時なので厳密に言えば違うけどまぁ実行してしまえば結果は一緒でしょ。

*2:BEGINブロックは実行前のコンパイル時に評価されるのでuseと同じ条件のはず。

*3:www14はどうしても無理だった…なんで?