Changeset 25141 for lang

Show
Ignore:
Timestamp:
11/27/08 21:28:44 (4 years ago)
Author:
yappo
Message:

add before & after

Location:
lang/perl/Shika/trunk
Files:
3 added
1 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/Shika/trunk/lib/Shika.pm

    r25139 r25141  
    2525        has      => {}, 
    2626        default  => {}, 
     27        modifier => {}, 
    2728    }; 
    2829 
    2930    no strict 'refs'; 
     31    *{"$pkg\::before"}  = \&_before; 
     32    *{"$pkg\::after"}   = \&_after; 
    3033    *{"$pkg\::meta"}    = sub { $meta }; 
    3134} 
     
    240243} 
    241244 
     245sub _install_modifier { 
     246    my($pkg, $name) = @_; 
     247    my $modifier = _init_modifier($pkg, $name); 
     248    my $before = $modifier->{before}; 
     249    my $after  = $modifier->{after}; 
     250    my $around = $modifier->{around}; 
     251 
     252    if (@$before && @$after) { 
     253        $modifier->{cache} = sub { 
     254            $_->(@_) for @{$before}; 
     255            my @rval; 
     256            ((defined wantarray) ? 
     257                ((wantarray) ? 
     258                    (@rval = $modifier->{around_cache}->(@_)) 
     259                    :   
     260                    ($rval[0] = $modifier->{around_cache}->(@_))) 
     261                :   
     262                $modifier->{around_cache}->(@_)); 
     263            $_->(@_) for @{$after}; 
     264            return unless defined wantarray; 
     265            return wantarray ? @rval : $rval[0]; 
     266        } 
     267    } elsif (@$before && !@$after) { 
     268        $modifier->{cache} = sub { 
     269            $_->(@_) for @{$before}; 
     270            return $modifier->{around_cache}->(@_); 
     271        } 
     272    } elsif (@$after && !@$before) { 
     273        $modifier->{cache} = sub { 
     274            my @rval; 
     275            ((defined wantarray) ? 
     276                ((wantarray) ? 
     277                    (@rval = $modifier->{around_cache}->(@_)) 
     278                    :   
     279                    ($rval[0] = $modifier->{around_cache}->(@_))) 
     280                :   
     281                $modifier->{around_cache}->(@_)); 
     282            $_->(@_) for @{$after}; 
     283            return unless defined wantarray; 
     284            return wantarray ? @rval : $rval[0]; 
     285        } 
     286    } else { 
     287        $modifier->{cache} = $modifier->{around_cache}; 
     288    } 
     289 
     290    no strict 'refs'; 
     291    no warnings 'redefine'; 
     292    *{"$pkg\::$name"} = sub { goto $modifier->{cache} }; 
     293} 
     294 
     295sub _init_modifier { 
     296    my($pkg, $name) = @_; 
     297    die "The method '$name' is not found in the inheritance hierarchy for class $pkg" 
     298        unless $pkg->can($name); 
     299    my $code = $pkg->can($name); 
     300    $pkg->meta->{modifier}->{$name} ||= +{ 
     301        around_cache => $code, 
     302        cache        => $code, 
     303        orig         => $code, 
     304        around       => [], 
     305        before       => [], 
     306        after        => [], 
     307    }; 
     308} 
     309 
     310sub _before { 
     311    my $pkg = caller(0); 
     312    my $name = shift; 
     313    my $modifier = _init_modifier($pkg, $name); 
     314    unshift @{ $modifier->{before} }, $_[0]; 
     315    _install_modifier($pkg, $name); 
     316} 
     317 
     318sub _after { 
     319    my $pkg = caller(0); 
     320    my $name = shift; 
     321    my $modifier = _init_modifier($pkg, $name); 
     322    push @{ $modifier->{after} }, $_[0]; 
     323    _install_modifier($pkg, $name); 
     324} 
     325 
     326# utils 
     327 
    242328sub _load_class { 
    243329    my $role = shift;