Carp::croakはなにもしないで使えるのではなく、なんかやってるから使える

勘違いする

いつも使っているCarp::croakなんですが、
完全修飾名で呼び出せる理由をあんまり考えてませんでした。

1. スクリプト

#!/usr/bin/perl
use strict;
use warnings;

Carp::croak("croak!!");

2. 実行

:!perl script/inc.pl
croak!! at script/inc.pl line 5

型グロブのコード部も見てみましょう

#!/usr/bin/perl
use strict;
use warnings;

warn *Carp::croak{CODE}; # コードリファレンスが記録されている

この事から、Carp::croakって何もしないで呼び出せるのは「標準モジュールかなんかだからそうなんじゃない」っていう壮大な勘違いをしたわけです。

勘違いに気づく

社内の勉強会用の資料作成でrequireを説明する為、次のコードを書いた。

#!/usr/bin/perl

for my $key ( keys %INC ) {
    print $key, " => ", $INC{$key}, "\n";
}

実行したけど%INCにはなにも入ってないのでなにも起きないとりあえずstrict, warningsをuseして、この2つだけを%INCに入れてみようとしたところで間違いに気づく。

!/usr/bin/perl
use strict;
use warnings;

for my $key ( keys %INC ) {
    print $key, " => ", $INC{$key}, "\n";
}

実行

:!perl %
Carp.pm => /usr/lib/perl5/5.8.8/Carp.pm
warnings.pm => /usr/lib/perl5/5.8.8/warnings.pm
Exporter.pm => /usr/lib/perl5/5.8.8/Exporter.pm
strict.pm => /usr/lib/perl5/5.8.8/strict.pm

俺はCarpをuseした覚えはないのだが??

結論

perldoc -m warnings

warnings.pm内で以下の記述がされているという

use Carp ();

とりあえずClass::Data::Inheritableでrequire Carp;している謎は解けた…。

2010-04-29追記

今回の記事で「warnings.pmがいつまでもuse Carp(); しているとは限らない」という指摘を社内からうけました、で、tokuhirom氏から頂いたコメントのようにこの書き方だと後日問題が発生します。

なので次のように書くと良いでしょう。

#!/usr/bin/perl
use strict;
use warnings;
use Carp ();

Carp::croak('!!');

Carp::croakではなく、croakで実行したい場合はシンボルをインポートします。

#!/usr/bin/perl
use strict;
use warnings;
use Carp qw/croak/;

croak('!!');