X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDevel%2FDeclare%2FMethodInstaller%2FSimple.pm;h=e285ea01aa6e09f07f236a5f85f0db379f336a8d;hb=4eeccf399bfe40aede5c2bc638eed248c96081f8;hp=0df21d1b65643db94e093a6024ef20dffb9efefd;hpb=e7be1784afaeb943f278a4249d5000bd2b706f11;p=p5sagit%2FDevel-Declare.git diff --git a/lib/Devel/Declare/MethodInstaller/Simple.pm b/lib/Devel/Declare/MethodInstaller/Simple.pm index 0df21d1..e285ea0 100644 --- a/lib/Devel/Declare/MethodInstaller/Simple.pm +++ b/lib/Devel/Declare/MethodInstaller/Simple.pm @@ -7,55 +7,78 @@ use Sub::Name; use strict; use warnings; +our $VERSION = '0.006008'; + sub install_methodhandler { - my $class = shift; - my %args = @_; - { - no strict 'refs'; - *{$args{into}.'::'.$args{name}} = sub (&) {}; - } - - my $ctx = $class->new( %args ); - Devel::Declare->setup_for( - $args{into}, - { $args{name} => { const => sub { $ctx->parser(@_) } } } - ); + my $class = shift; + my %args = @_; + { + no strict 'refs'; + *{$args{into}.'::'.$args{name}} = sub (&) {}; + } + + my $warnings = warnings::enabled("redefine"); + my $ctx = $class->new(%args); + Devel::Declare->setup_for( + $args{into}, + { $args{name} => { const => sub { $ctx->parser(@_, $warnings) } } } + ); +} + +sub code_for { + my ($self, $name) = @_; + + if (defined $name) { + my $pkg = $self->get_curstash_name; + $name = join( '::', $pkg, $name ) + unless( $name =~ /::/ ); + return sub (&) { + my $code = shift; + # So caller() gets the subroutine name + no strict 'refs'; + my $installer = $self->warning_on_redefine + ? sub { *{$name} = subname $name => $code; } + : sub { no warnings 'redefine'; + *{$name} = subname $name => $code; }; + $installer->(); + return; + }; + } else { + return sub (&) { shift }; + } +} + +sub install { + my ($self, $name ) = @_; + $self->shadow( $self->code_for($name) ); } sub parser { - my $ctx = shift; - $ctx->init(@_); - - $ctx->skip_declarator; - my $name = $ctx->strip_name; - my $proto = $ctx->strip_proto; - my @decl = $ctx->parse_proto($proto); - my $inject = $ctx->inject_parsed_proto(@decl); - if( defined $name ) { - $inject = $ctx->scope_injector_call() . $inject; - } - $ctx->inject_if_block($inject); - if( defined $name ) { - my $pkg = $ctx->get_curstash_name; - $name = join( '::', $pkg, $name ) - unless( $name =~ /::/ ); - $ctx->shadow( sub (&) { - my $code = shift; - # So caller() gets the subroutine name - no strict 'refs'; - *{$name} = subname $name => $code; - }); - } else { - $ctx->shadow(sub (&) { shift }); - } + my $self = shift; + $self->init(@_); + + $self->skip_declarator; + my $name = $self->strip_name; + my $proto = $self->strip_proto; + my $attrs = $self->strip_attrs; + my @decl = $self->parse_proto($proto); + my $inject = $self->inject_parsed_proto(@decl); + if (defined $name) { + $inject = $self->scope_injector_call() . $inject; + } + $self->inject_if_block($inject, $attrs ? "sub ${attrs} " : ''); + + $self->install( $name ); + + return; } -sub parse_proto { } + +sub parse_proto { '' } + sub inject_parsed_proto { - my $ctx = shift; - shift; + return $_[1]; } - 1;