Perlでクラス(モジュール)をアンロードする方法として、Class::Unloadを使っています。
Class::Unload->unload('Some::Unneeded::Class');
当初、木本さん(perlcodesampleさん)による「クラスをアンロードする方法」の記事や、そこで言及されているClass::MOP::Class::DESTROY()を参考にして、以下のようなアンロードメソッドも書いてみました。その後、用途に適合するClass::UnloadモジュールがCPANで公開されていることが分かったので、自分の場合はこれを活用させていただこうと思った次第です。
いつの日かClass::Unloadがどうしても使えない場面に立ち会ってしまったら、これを引っ張り出してこようと思います。「だが、私はCPANを使えない!」の全ての処方箋が通用しないという、あまりぞっとしない場面ですが......。
sub _unload_class {
my ($self, $class) = @_;
my @route_to_class = split '::', $class;
# unload class in target library which is dump target of generated classes
# cf. http://d.hatena.ne.jp/perlcodesample/20091101/1246274997
# below codes stolen from Class::MOP::Class::DESTROY()
{
no strict 'refs';
# delete inheritance information from @ISA
@{
$class . '::ISA'
} = ();
# delete class symbol from symbol table
%{
$class . '::'
} = ();
# delete class symbol from upper namespace
delete ${
join '::', @route_to_class[0 .. $#route_to_class - 1], q{}
}{
$route_to_class[-1] . '::'
};
# delete loading information
delete $INC{
(join '/', @route_to_class ) . '.pm'
};
}
return;
}
なお、上記はとあるクラスのメソッドとして実装していますが、$selfは使っていないので、単なるサブルーチンにも出来ます。
ところで、普通に暮らしているだけではクラスをアンロードしたいと思う場合が殆ど全くありません。アンロードしたいという稀少な事例の一つとして、拙作のDBICx::Modeler::Generatorでクラスをリロードするという例を掲げておきます(該当箇所はfcf4b0de...コミットに於けるDBICx::Modeler::Generator::Classの147行目です)。
このモジュールについては稿を改めてご紹介するつもりです。
最近のコメント