From: Florian Ragwitz Date: Mon, 27 Oct 2008 20:27:13 +0000 (+0000) Subject: Refactor MethodInstaller::Simple. X-Git-Tag: 0.005000~38 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit%2FDevel-Declare.git;a=commitdiff_plain;h=a664754d8ce3736abcfeb16ea5115d99cec724fd;hp=72a03bb0f3ba57200f70eb56f2f239a6a19efdb3 Refactor MethodInstaller::Simple. It now has code_for() which the subclass can override to monkey with the magic shadowed subroutine. This is handy if you want to employ Devel::BeginLift. --- diff --git a/lib/Devel/Declare/MethodInstaller/Simple.pm b/lib/Devel/Declare/MethodInstaller/Simple.pm index 9a11911..e8b5668 100644 --- a/lib/Devel/Declare/MethodInstaller/Simple.pm +++ b/lib/Devel/Declare/MethodInstaller/Simple.pm @@ -67,6 +67,31 @@ sub strip_attrs { return $attrs; } +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'; + *{$name} = subname $name => $code; + return; + }; + } else { + return sub (&) { shift }; + } +} + +sub install { + my ($self, $name ) = @_; + + $self->shadow( $self->code_for($name) ); +} + sub parser { my $self = shift; $self->init(@_); @@ -81,19 +106,10 @@ sub parser { $inject = $self->scope_injector_call() . $inject; } $self->inject_if_block($inject, $attrs ? "sub ${attrs} " : ''); - if (defined $name) { - my $pkg = $self->get_curstash_name; - $name = join( '::', $pkg, $name ) - unless( $name =~ /::/ ); - $self->shadow( sub (&) { - my $code = shift; - # So caller() gets the subroutine name - no strict 'refs'; - *{$name} = subname $name => $code; - }); - } else { - $self->shadow(sub (&) { shift }); - } + + $self->install( $name ); + + return; } sub parse_proto { } diff --git a/t/methinstaller-simple.t b/t/methinstaller-simple.t index 62400ee..6e082e0 100644 --- a/t/methinstaller-simple.t +++ b/t/methinstaller-simple.t @@ -1,3 +1,14 @@ +#!/usr/bin/perl -w + +use strict; +use Test::More 'no_plan'; + +my $Have_Devel_BeginLift; +BEGIN { + # setup_for_cv() introduced in 0.001001 + $Have_Devel_BeginLift = eval q{ use Devel::BeginLift 0.001001; 1 }; +} + { package MethodHandlers; @@ -23,6 +34,17 @@ return $inject; } + sub code_for { + my($self, $name) = @_; + + my $code = $self->SUPER::code_for($name); + + if( defined $name and $Have_Devel_BeginLift ) { + Devel::BeginLift->setup_for_cv($code); + } + + return $code; + } } my ($test_method1, $test_method2, @test_list); @@ -37,6 +59,13 @@ my ($test_method1, $test_method2, @test_list); ); } + # Test at_BEGIN + SKIP: { + ::skip "Need Devel::BeginLift for compile time methods", 1 + unless $Have_Devel_BeginLift; + ::can_ok( "DeclareTest", qw(new foo upgrade) ); + } + method new { my $class = ref $self || $self; return bless({ @_ }, $class); @@ -69,7 +98,6 @@ my ($test_method1, $test_method2, @test_list); method leftie($left) : method { $self->{left} ||= $left; $self->{left} }; } -use Test::More 'no_plan'; my $o = DeclareTest->new(attr => "value");