Permalink
Browse files

Containerの拡張

  • Loading branch information...
1 parent 201de1c commit 1c230ad72c7f679a285a7f8c8753798571de4879 @nekokak committed Oct 29, 2009
Showing with 45 additions and 5 deletions.
  1. +25 −4 lib/Kamui/Container.pm
  2. +6 −1 t/010_container/export.t
  3. +12 −0 t/lib/Mock/Api/Form/Foo.pm
  4. +2 −0 t/lib/Mock/Container.pm
View
@@ -3,10 +3,11 @@ use Kamui;
use base 'Class::Singleton';
use Exporter::AutoClean;
use UNIVERSAL::require;
-use Carp;
use String::CamelCase qw/camelize/;
use Path::Class qw/file dir/;
+my $_register_namespace = +{};
+
sub import {
my ($class, @opts) = @_;
my $caller = caller;
@@ -21,10 +22,12 @@ sub import {
push @{"${caller}::ISA"}, $class;
}
- my $r = $class->can('register');
+ my $register = $class->can('register');
+ my $register_namespace = $class->can('register_namespace');
Exporter::AutoClean->export(
$caller,
- register => sub { $r->($caller, @_) },
+ register => sub { $register->($caller, @_) },
+ register_namespace => sub { $register_namespace->($caller, @_) },
);
return;
}
@@ -86,12 +89,14 @@ sub _export_functions {
for my $name (@export_names) {
+ next if $caller->can($name);
if ($caller->can($name)) { die qq{can't export $name for $caller. $name already defined in $caller.} }
- my $code = sub {
+ my $code = $_register_namespace->{$name} || sub {
my $target = shift;
my $container_name = join '::', $class->base_name, camelize($name), camelize($target);
return $target ? $class->get($container_name) : $class;
};
+
{
no strict 'refs';
*{"${caller}::${name}"} = $code;
@@ -131,6 +136,22 @@ sub register {
$self->{_registered_classes}->{$class} = $initializer;
}
+sub register_namespace {
+ my ($self, $method, $pkg) = @_;
+ $self = $self->instance unless ref $self;
+ my $class = ref $self;
+
+ $pkg = camelize($pkg);
+ my $code = sub {
+ my $target = shift;
+ my $container_name = join '::', $pkg, camelize($target);
+ $self->load_class($container_name);
+ return $target ? $class->get($container_name) : $class;
+ };
+
+ $_register_namespace->{$method} = $code;
+}
+
sub get {
my ($self, $class) = @_;
$self = $self->instance unless ref $self;
View
@@ -1,6 +1,6 @@
use t::Utils;
use Test::Declare;
-use Mock::Container qw/api/;
+use Mock::Container qw/api form/;
plan tests => blocks;
@@ -11,6 +11,11 @@ describe 'container tests' => run {
is api('baz')->say, 'baz';
dies_ok(sub { api('hoge') }, q{can't get hoge.});
};
+
+ test 'export form' => run {
+ isa_ok form('foo'), 'Mock::Api::Form::Foo';
+ is form('foo')->say, 'foo';
+ };
};
View
@@ -0,0 +1,12 @@
+package Mock::Api::Form::Foo;
+use Kamui;
+
+sub new {
+ my $class = shift;
+ bless {}, $class;
+}
+
+sub say { 'foo' }
+
+1;
+
View
@@ -1,6 +1,8 @@
package Mock::Container;
use Kamui::Container -base;
+register_namespace form => 'Mock::Api::Form';
+
register 'foo' => sub {
my $self = shift;
$self->load_class('Mock::Foo');

0 comments on commit 1c230ad

Please sign in to comment.