perlを扱っていると、よく以下のようなエラーが出ることがあります。
Can't locate Sample/Module.pm in @INC
今回は、このエラーの原因と「これをやったら解決するよ」と言う対策法を紹介していきます。
Can’t locate Sample/Module.pm in @INCの原因とは?
上記のエラーが発生する原因として、use Sample::Module
などでモジュールを読み込む時に、以下の原因でモジュールが正しく読み込まれていない可能性があります。
- モジュールのパスの設定が適切ではない
- そもそもモジュールが入っていな
- タイプミス(
use Simple::MaDula
とか)
上記エラー文のCan't locate Sample/Module.pm in @INC
は、「@INC
配列の中でModule.pmを見つけれないよ」と言う意味ですが、perlはモジュールを読み込む時に@INC
配列内に書かれているディレクトリから、モジュールを見つけようとします。
つまり、上記エラーの原因として、@INC
に適切にモジュールのディレクトリが定義されていない場合も考えられます。
Can’t locate Module.pm in @INCの対処法3つ
以下は、僕がエラーに会った時に大体解決する方法を3つ紹介していきます。
1,モジュールの存在の可否&ディレクトリをチェックする
このエラーを解決するためには、そもそもモジュールが入っているのか、自分が読み込みたいモジュールがどのディレクトリにあるのかをチェックしてみます。
(これを最初にやらないと、思わぬ所にモジュールが入っていて後で地獄を見ます。あと、perlのバージョンの違い等によって、最初から入っている標準モジュールが異なる場合もあるので注意。)
例えば、XML::Simple
がどこにあるかをチェックする場合は、ターミナル上で以下のコマンドを実行すると良いです。
perldoc -l XML::Simple = result /usr/share/perl5/vendor_perl/XML/Simple.pm
もし、モジュールがインストールされていればディレクトリを表示してくれますし、モジュールがインストールされていなければNo documentation found for "XML::Simple".
と表示してくれます。
もし、モジュールが存在していなければ、cpanm XML::Simple
などでインストールすればOKです。
参考:How can I check if a Perl module is installed on my system from the command line? – Stack Overflow
2,@INC変数内のディレクトリをチェックする
次に、@INC
変数内のディレクトリをチェックしていきます。
やり方は、ターミナル上で以下のコマンドを実行するだけです。
perl -e 'print "$_\n" foreach @INC'
上記のコマンドを実行すると、僕の環境では以下の結果が出ました。
/home/username/perl5/lib/perl5/5.16.3/x86_64-linux-thread-multi /home/username/perl5/lib/perl5/5.16.3 /home/username/perl5/lib/perl5/x86_64-linux-thread-multi /home/username/perl5/lib/perl5 /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .
上記の結果を見て、お目当のモジュールがきちんと読み込まれているかチェックしましょう。
例えば、先ほどの調べたモジュールの絶対パスは/usr/share/perl5/vendor_perl/XML/Simple.pm
だったので、上記の結果に/usr/share/perl5/vendor_perl/
が含まれていれば、モジュールは読み込まれます。(なので、コードを見てuse XXL::SAmple
のようなタイプミスをしていないかチェック。)
3, @INCにモジュールのディレクトリを追加する
ここまで来て解決しなければ、以下のように@INC
変数にディレクトリを追加すると良いです。
# Myapp/script/myapp.pl use strict; use warnings; BEGIN { unshift @INC, "/usr/share/perl5/vendor_perl/" } use XML::Simple;
ポイントは、BEGIN { unshift @INC, "/usr/share/perl5/vendor_perl/" }
の部分です。BEGIN{}
のブロック内に@INC
変数にディレクトリを追加する処理を書くことで、他の処理よりも早く実行してくれます。
その結果、use Xml::Simple
とモジュールを読みだした時に、perlが/usr/share/perl5/vendor_perl/XML/Simple.pm
を見つけて読み込んでくれるようになります。