Class::Load を使う(try_load_class と load_optional_class)
Class::Load、動的にモジュールを読み込んでくれて、しかも require より柔軟で、便利です。
で、Class::Load::try_load_class を使っていたのですが、ロード先がコンパイルエラーとかになっている場合に、0 が返ってきてしまうんですね。die してほしいなー、と思ったのです。
try_load_class は、配列コンテキストだと、2番目の値にエラーメッセージを返すので、コレ見て何とかしよう、と思って、試しにこんなの書いた。
#!perl use strict; use warnings; use Class::Load qw(try_load_class); { my ($status, $message) = try_load_class('Net::FTP');#ある warn $status, $message;# $status => 1, $message => undef } { my ($status, $message) = try_load_class('Net::FCP');#そんなのない warn $status, $message;# $status => 0, $message => 'Can't locate Net/FCP.pm in @INC (@INC contains: ...' } { my ($status, $message) = try_load_class('a');#コンパイルエラー a.pm => "package a;0;#コンパイルエラー"; warn $status, $message;# $status => 0, $message => 'a.pm did not return a true value at ...' }
で、「Can't locate ...」ってオフィシャルのドキュメントにあるかなー?とか思って、perldiag みて見たりとかしてたんだけど、ふと我に返って Class::Load のドキュメント見てたら、
load_optional_class Class::Name, \%options -> 0|1
load_optional_class is a lot like try_load_class, but also a lot like load_class.
(中略)
If the class exists on disk, but loading from disk results in an error ( i.e.: a syntax error ), then it will croak with that error.
あ゛、あったw
#!perl use strict; use warnings; use Class::Load qw(load_optional_class); { my $status = load_optional_class('Net::FTP');#ある warn $status; # $status => 1 } { my $status = load_optional_class('Net::FCP');#そんなのない warn $status; # $status => 0 } { my $status = load_optional_class('a');#コンパイルエラー a.pm => "package a;0;#コンパイルエラー"; warn $status; #ここに来れずに手前でしぬ。'a.pm did not return a true value at ...' }
うん、意図どおりの挙動です。名前に騙されて、ちゃんとドキュメント読んでなかったわー orz
モジュールのドキュメントはちゃんと読まないとダメですねー。