File Coverage

blib/lib/MooseX/Callbacks.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package MooseX::Callbacks;
2              
3 1     1   25861 use Moose::Role;
  0            
  0            
4             use Try::Tiny;
5             use namespace::autoclean;
6              
7             # \%event => [ \&cb1, \&cb2 ... ]
8             has '_callbacks' => (
9             is => 'rw',
10             isa => 'HashRef[ArrayRef[CodeRef]]',
11             default => sub { {} },
12             lazy => 1,
13            
14             traits => ['Hash'],
15             handles => {
16             set_callbacks => 'set',
17             get_callbacks => 'get',
18             clear_callbacks => 'delete',
19             has_callbacks => 'exists',
20             },
21             );
22              
23             =head1 NAME
24              
25             MooseX::Callbacks - Add ability to register and call callbacks with a role.
26              
27             =head1 VERSION
28              
29             Version 0.01
30              
31             =cut
32              
33             our $VERSION = '0.01';
34              
35             =head1 SYNOPSIS
36              
37             package Foo;
38             use Moose;
39             with 'MooseX::Callbacks';
40              
41             ...
42              
43             my $foo = Foo->new;
44             $foo->register_callbacks(ding => \&dong);
45             $foo->dispatch('ding', $arg1, $arg2...);
46              
47             =head1 ATTRIBUTES
48              
49             =head2 _callbacks
50              
51             Hashref of arrayrefs of callbacks. Delegates via native traits C<set_callbacks>, C<get_callbacks>, C<clear_callbacks>, C<has_callbacks>
52              
53             =head1 METHODS
54              
55             =head2 register_callback($event => \&callback)
56              
57             Same as C<register_callbacks>
58              
59             =head2 register_callbacks(event1 => \&callback[, event2 => \&callback2 ...])
60              
61             Registers callbacks for given events. Should be coderefs.
62              
63             =cut
64              
65             *register_callback = \&register_callbacks;
66             sub register_callbacks {
67             my ($self, %cbs) = @_;
68            
69             foreach my $k (keys %cbs) {
70             $self->_callbacks->{$k} ||= [];
71              
72             # don't add the same callback twice
73             next if grep { $_ == $cbs{$k} } @{ $self->get_callbacks($k) };
74            
75             push @{ $self->get_callbacks($k) }, $cbs{$k};
76             }
77             }
78              
79             =head2 dispatch($event, @args)
80              
81             Calls callbacks for $event with @args as parameters.
82              
83             =cut
84              
85              
86             sub dispatch {
87             my ($self, $event, @extra) = @_;
88              
89             my $cbs = $self->get_callbacks($event);
90              
91             if (! $cbs || ! @$cbs) {
92             #warn("unhandled callback on $self: $event");
93             return 0;
94             }
95              
96             # call each registered callback
97             foreach my $cb (@$cbs) {
98             try {
99             $cb->(@extra);
100             } catch {
101             my $err = shift;
102             warn "Error calling callback for '$event': $err";
103             };
104             }
105              
106             return 1;
107             }
108              
109             =head1 TODO
110              
111             Ability to unregister callbacks.
112              
113             =head1 AUTHOR
114              
115             Mischa Spiegelmock, C<< <revmischa at cpan.org> >>
116              
117             =head1 SUPPORT
118              
119             You can find documentation for this module with the perldoc command.
120              
121             perldoc MooseX::Callbacks
122              
123             =head1 ACKNOWLEDGEMENTS
124              
125             Nobody.
126              
127             =head1 LICENSE AND COPYRIGHT
128              
129             Copyright 2012 Mischa Spiegelmock.
130              
131             This program is free software; you can redistribute it and/or modify it
132             under the terms of either: the GNU General Public License as published
133             by the Free Software Foundation; or the Artistic License.
134              
135             See http://dev.perl.org/licenses/ for more information.
136              
137             =cut
138              
139             1;