Changeset 2177

Show
Ignore:
Timestamp:
03/03/07 18:25:50
Author:
jesse
Message:

r52908@152: jesse | 2007-03-03 01:15:42 +0000

  • Support for abortable triggers
  • Support for capturing trigger return values


Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • Class-Trigger/branches/return-values/lib/Class/Trigger.pm

    r2172 r2177  
    33use strict; 
    44use vars qw($VERSION); 
    5 $VERSION = "0.11"; 
     5$VERSION = "0.11_01"; 
    66 
    77use Carp (); 
     
    1717    # export mixin methods 
    1818    no strict 'refs'; 
    19     my @methods = qw(add_trigger call_trigger); 
     19    my @methods = qw(add_trigger call_trigger last_trigger_results); 
    2020    *{"$pkg\::$_"} = \&{$_} for @methods; 
    2121} 
     
    2525 
    2626    my $triggers = __fetch_triggers($proto); 
     27 
     28    if (ref($_[1]) eq 'CODE') {  
     29 
    2730    while (my($when, $code) = splice @_, 0, 2) { 
    2831        __validate_triggerpoint($proto, $when); 
    2932        Carp::croak('add_trigger() needs coderef') unless ref($code) eq 'CODE'; 
    30         push @{$triggers->{$when}}, $code; 
    31     } 
    32  
     33        push @{$triggers->{$when}}, [$code, undef]; 
     34    } 
     35    } 
     36    elsif (grep {'name'} @_) { 
     37        my %args = ( name => undef, callback => undef, abortable => undef, @_); 
     38        my $when= $args{'name'}; 
     39        my $code = $args{'callback'}; 
     40        my $abortable = $args{'abortable'}; 
     41        __validate_triggerpoint($proto, $when); 
     42        Carp::croak('add_trigger() needs coderef') unless ref($code) eq 'CODE'; 
     43        push @{$triggers->{$when}}, [$code, $abortable]; 
     44 
     45 
     46    } else { 
     47        Carp::croak('add_trigger() needs coderef'); 
     48 
     49    } 
    3350    1; 
     51} 
     52 
     53 
     54sub last_trigger_results { 
     55    my $self = shift; 
     56    my $result_store = ref($self) ? $self : ${Class::Trigger::_trigger_results}->{$self}; 
     57    return $result_store->{'_class_trigger_results'}; 
    3458} 
    3559 
     
    3862    my $when = shift; 
    3963 
     64    my @return; 
     65 
     66    my $result_store = ref($self) ? $self : ${Class::Trigger::_trigger_results}->{$self}; 
     67 
     68    $result_store->{'_class_trigger_results'} = []; 
     69 
    4070    if (my @triggers = __fetch_all_triggers($self, $when)) { # any triggers? 
    41         $_->($self, @_) for @triggers; 
     71        for (@triggers) { 
     72              my @return = $_->[0]->($self, @_); 
     73                push @{$result_store->{'_class_trigger_results'}}, \@return; 
     74                return undef if ($_->[1] and not $return[0]); # only abort on false values. 
     75          
     76    } 
    4277    } 
    4378    else { 
     
    4782        __validate_triggerpoint($self, $when); 
    4883    } 
     84 
     85    return scalar @{$result_store->{'_class_trigger_results'}}; 
    4986} 
    5087 
     
    149186=head1 METHODS 
    150187 
    151 By using this module, your class is capable of following two methods. 
     188By using this module, your class is capable of following methods. 
    152189 
    153190=over 4 
     
    158195  $foo->add_trigger($triggerpoint => $sub); 
    159196 
     197 
     198  Foo->add_trigger( name => $triggerpoint, 
     199                    callback => sub {return undef}, 
     200                    abortable => 1);  
     201 
     202  # no further triggers will be called. Undef will be returned. 
     203 
     204 
    160205Adds triggers for trigger point. You can have any number of triggers 
    161 for each point. Each coderef will be passed a the object reference, and 
    162 return values will be ignored. 
     206for each point. Each coderef will be passed a reference to the calling object,  
     207as well as arguments passed in via L<call_trigger>. Return values will be 
     208captured in I<list context>. 
     209 
     210If add_trigger is called with named parameters and the C<abortable> 
     211parameter is passed a true value, a false return value from trigger 
     212code will stop processing of this trigger point and return a C<false> 
     213value to the calling code. 
     214 
     215If C<add_trigger> is called without the C<abortable> flag, return 
     216values will be captured by call_trigger, but failures will be ignored. 
    163217 
    164218If C<add_trigger> is called as object method, whole current trigger 
     
    185239Triggers are invoked in the same order they were defined. 
    186240 
     241If there are no C<abortable> triggers or no C<abortable> trigger point returns  
     242a false value, C<call_trigger> will return the number of triggers processed. 
     243 
     244 
     245If an C<abortable> trigger returns a false value, call trigger will stop execution 
     246of the trigger point and return undef. 
     247 
     248=item last_trigger_results 
     249 
     250    my @results = @{ $foo->last_trigger_results }; 
     251 
     252Returns a reference to an array of the return values of all triggers called 
     253for the last trigger point. Results are ordered in the same order the triggers 
     254were run. 
     255 
     256 
    187257=back 
    188258