perlで「Can't locate Sample/Module.pm in @INC」と言うエラーが起こる原因と対処法3つ

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を見つけて読み込んでくれるようになります。

ReratedPosts

perlでIO::Socketを使う時に「permission deny」と言うエラーが出た時の対処法
perlのgrep関数の使い方|変数とか戻り値とか複数条件とかのまとめ
Mojoliciousで「Can't use string ("Controller") as a HASH ref while "strict refs" in use」のエラーが発生した時の対策
perlのコードでよく見かけるrequire、use、BEGINの役割や関係についてまとめる
perlでファイルの中身を全て読み込みたい時の方法
Perlモジュール「Moo」(Moose)の使い方をまとめてみる