diff --git a/lib/Kelp.pm b/lib/Kelp.pm index eef41ab..f434256 100644 --- a/lib/Kelp.pm +++ b/lib/Kelp.pm @@ -43,6 +43,8 @@ attr -loaded_modules => sub { {} }; attr req => undef; attr res => undef; +attr -registered_methods => sub { {} }; + # Initialization sub new { my $self = shift->SUPER::new(@_); @@ -80,6 +82,30 @@ sub _clone { return bless { %$self }, $subclass; } +# Check our instance-registered methods for can() +sub can { + my ($self, $name) = @_; + if (ref $self) { + my $method = $self->registered_methods->{$name}; + return $method if defined $method; + } + return $self->SUPER::can($name); +} + +# Check our instance-registered methods for implementations +our $AUTOLOAD; +sub AUTOLOAD { + my $self = shift; + + my $name = $AUTOLOAD =~ s/.*:://r; + return if $name eq "DESTROY"; + + my $method = $self->can($name); + return $self->$method(@_) if $method; + die sprintf('Can\'t locate object method "%s" via package "%s"', + $name, ref $self); +} + sub load_module { my ( $self, $name, %args ) = @_; diff --git a/lib/Kelp/Module.pm b/lib/Kelp/Module.pm index a53c6de..7e2a003 100644 --- a/lib/Kelp/Module.pm +++ b/lib/Kelp/Module.pm @@ -22,20 +22,17 @@ sub register { no strict 'refs'; no warnings 'redefine'; - my $app = ref $self->app; - my $glob = "${app}::$name"; - # Manually check if the glob is being redefined if ( !$ENV{KELP_REDEFINE} && $self->app->can($name) ) { - croak "Redefining of $glob not allowed"; + croak "Redefining of $name not allowed"; } if ( ref $item eq 'CODE' ) { - *{$glob} = $item; + $self->app->registered_methods->{$name} = $item; } else { $self->app->{$name} = $item; - *{$glob} = sub { $_[0]->{$name} } + $self->app->registered_methods->{$name} = sub { $_[0]->{$name} }; } } } diff --git a/t/module_config.t b/t/module_config.t index 3b76bc1..c04ea1a 100644 --- a/t/module_config.t +++ b/t/module_config.t @@ -10,11 +10,10 @@ use Plack::Util; use FindBin '$Bin'; use Test::More; use Test::Exception; +use Kelp; # Basic -my $app = Plack::Util::inline_object( - mode => sub { "test" } -); +my $app = Kelp->new( mode => 'test' ); my $c = Kelp::Module::Config->new( app => $app ); isa_ok $c, 'Kelp::Module::Config';