URI.pm っぽいモジュール名用クラス
を考えてみました。
use Module::Class; Module::Class->module('CGI')->require or die $@;
それ UNIVERSAL::require (ry
というのは冗談ですが
# with Module::Class::Plugin::Module::CoreList; print Module::Class->module('File::Spec')->first_release();
みたいにプラグインで拡張できるもの。
なぜ Module::Name という名前じゃないかというと
Module::Class->modules(qw( CGI HTTP::Request ))->require() or die $@; Module::Class->module('HogeHoge')->findsubmod()->require();
みたく配列とか他のモジュールの戻り値を活用できたらおもしろいかな,と(今回はそこまでインプリメントしてません)。てか Path::Class インスパイアドなだけです。
CPAN になさそうだし,なんとなく必要になって書いてみたんですが,いざ書いてみたら使い道がなかったです。でも Object::Declare について勉強になったからいいや。
package Module::Class; use strict; use warnings; use overload q{""} => sub { ${$_[0]} }, q{==} => sub { overload::StrVal($_[0]) eq overload::StrVal($_[1]) }, fallback => 1; use Module::Pluggable require => 1; BEGIN { __PACKAGE__->plugins() } # load plugins sub module { my ($class, $module) = @_; return bless \$module, $class; } 1;
package Module::Class::Plugin; use strict; use warnings; use Exporter::Lite; use UNIVERSAL::require; our @EXPORT = qw( from methods method ); use Object::Declare declarator => 'methods', copula => { is => sub { is => @_ }, as => sub { as => @_ }, }, mapping => { method => sub { return { @_ }; }, }, ; sub from { my ($module, %methods) = @_; return if ! $module->require; while (my ($method, $args) = each %methods) { my $method_in_module = defined $args->{as} ? $args->{as} : $method; if ($args->{is} eq 'class_method') { my $sub = sub { my $self = shift; return $module->$method_in_module($$self, @_); }; no strict 'refs'; *{"Module::Class::${method}"} = $sub; } } } 1;
プラグインの例
package Module::Class::Plugin::require; use strict; use warnings; use UNIVERSAL::require; sub Module::Class::require { my $self = shift; return UNIVERSAL::require($$self, @_); } 1;
package Module::Class::Plugin::Module::CoreList; use strict; use warnings; use Module::Class::Plugin; BEGIN { from 'Module::CoreList', methods { method first_release => is class_method; method first_release_by_date => is class_method; }; } 1;