tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

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

モジュールのドキュメントはちゃんと読まないとダメですねー。