File Coverage

blib/lib/MooseX/WhatTheTrig.pm
Criterion Covered Total %
statement 43 43 100.0
branch n/a
condition n/a
subroutine 14 14 100.0
pod n/a
total 57 57 100.0


line stmt bran cond sub pod time code
1 1     1   723783 use 5.008008;
  1         4  
  1         39  
2 1     1   6 use strict;
  1         3  
  1         36  
3 1     1   5 use warnings;
  1         6  
  1         31  
4              
5 1     1   6 use Moose ();
  1         2  
  1         14  
6 1     1   5 use Moose::Exporter ();
  1         7  
  1         82  
7              
8             package MooseX::WhatTheTrig;
9              
10             our $AUTHORITY = 'cpan:TOBYINK';
11             our $VERSION = '0.001';
12              
13             {
14             package MooseX::WhatTheTrig::Trait::Attribute;
15             our $AUTHORITY = 'cpan:TOBYINK';
16             our $VERSION = '0.001';
17 1     1   6 use Moose::Role;
  1         1  
  1         8  
18 1     1   7260 use Scope::Guard qw(guard);
  1         461  
  1         234  
19            
20             after _process_trigger_option => sub
21             {
22             my $class = shift;
23             my ($name, $opts) = @_;
24             return unless exists $opts->{trigger};
25            
26             my $orig = delete $opts->{trigger};
27             $opts->{trigger} = sub
28             {
29             my $self = shift;
30             my $meta = Moose::Util::find_meta($self);
31             my $restore = $meta->triggered_attribute;
32             my $guard = guard { $meta->_set_triggered_attribute($restore) };
33             $meta->_set_triggered_attribute($name);
34             $self->$orig(@_);
35             };
36             }
37             }
38              
39             {
40             package MooseX::WhatTheTrig::Trait::Package;
41             our $AUTHORITY = 'cpan:TOBYINK';
42             our $VERSION = '0.001';
43 1     1   6 use Moose::Role;
  1         2  
  1         8  
44            
45             has triggered_attribute => (
46             is => 'ro',
47             writer => '_set_triggered_attribute',
48             );
49             }
50              
51             {
52             package MooseX::WhatTheTrig::Trait::Class;
53             our $AUTHORITY = 'cpan:TOBYINK';
54             our $VERSION = '0.001';
55 1     1   6345 use Moose::Role;
  1         3  
  1         6  
56             with qw(MooseX::WhatTheTrig::Trait::Package);
57             }
58              
59             {
60             package MooseX::WhatTheTrig::Trait::Role;
61             our $AUTHORITY = 'cpan:TOBYINK';
62             our $VERSION = '0.001';
63 1     1   6008 use Moose::Role;
  1         2  
  1         6  
64             with qw(MooseX::WhatTheTrig::Trait::Package);
65             }
66              
67             my %class_metaroles = (
68             class => ['MooseX::WhatTheTrig::Trait::Class'],
69             );
70              
71             my %role_metaroles = (
72             role => ['MooseX::WhatTheTrig::Trait::Role'],
73             application_to_role => ['MooseX::WhatTheTrig::Trait::ApplicationToRole'],
74             application_to_class => ['MooseX::WhatTheTrig::Trait::ApplicationToClass'],
75             );
76              
77             'Moose::Exporter'->setup_import_methods(
78             trait_aliases => [ [ 'MooseX::WhatTheTrig::Trait::Attribute' => 'WhatTheTrig' ] ],
79             class_metaroles => \%class_metaroles,
80             role_metaroles => \%role_metaroles,
81             );
82              
83             {
84             package MooseX::WhatTheTrig::Trait::Application;
85             our $AUTHORITY = 'cpan:TOBYINK';
86             our $VERSION = '0.001';
87 1     1   6447 use Moose::Role;
  1         3  
  1         6  
88            
89             sub _whatthetrig_metacrap
90             {
91 2     2   4 my $self = shift;
92 2         5 my ($next, $opts, $role, $applied_to) = @_;
93 2         13 $applied_to = Moose::Util::MetaRole::apply_metaroles(for => $applied_to, %$opts);
94 2         5050 $self->$next($role, $applied_to);
95             }
96             }
97              
98             {
99             package MooseX::WhatTheTrig::Trait::ApplicationToClass;
100             our $AUTHORITY = 'cpan:TOBYINK';
101             our $VERSION = '0.001';
102 1     1   5966 use Moose::Role;
  1         3  
  1         5  
103             with qw(MooseX::WhatTheTrig::Trait::Application);
104            
105             around apply => sub
106             {
107             my $next = shift;
108             my $self = shift;
109             $self->_whatthetrig_metacrap($next, { class_metaroles => \%class_metaroles }, @_);
110             };
111             }
112              
113             {
114             package MooseX::WhatTheTrig::Trait::ApplicationToRole;
115             our $AUTHORITY = 'cpan:TOBYINK';
116             our $VERSION = '0.001';
117 1     1   5632 use Moose::Role;
  1         2  
  1         6  
118             with qw(MooseX::WhatTheTrig::Trait::Application);
119            
120             around apply => sub
121             {
122             my $next = shift;
123             my $self = shift;
124             $self->_whatthetrig_metacrap($next, { role_metaroles => \%role_metaroles }, @_);
125             };
126             }
127              
128             1;
129              
130             __END__
131              
132             =pod
133              
134             =for stopwords metaobject
135              
136             =encoding utf-8
137              
138             =head1 NAME
139              
140             MooseX::WhatTheTrig - what attribute triggered me?
141              
142             =head1 SYNOPSIS
143              
144             use v5.14;
145            
146             package Goose {
147             use Moose;
148             use MooseX::WhatTheTrig;
149            
150             has foo => (
151             traits => [ WhatTheTrig ],
152             is => 'rw',
153             trigger => sub {
154             my $self = shift;
155             my $attr = Moose::Util::find_meta($self)->triggered_attribute;
156             say "Triggered $attr";
157             },
158             );
159             }
160            
161             my $obj = Goose->new(foo => 42); # says "Triggered foo"
162             $obj->foo(999); # says "Triggered foo"
163              
164             =head1 DESCRIPTION
165              
166             Moose trigger subs get passed two (sometimes three) parameters:
167              
168             =over
169              
170             =item *
171              
172             The object itself.
173              
174             =item *
175              
176             The new attribute value.
177              
178             =item *
179              
180             The old attribute value (if any).
181              
182             =back
183              
184             The sub doesn't get told which attribute triggered it. This may present
185             a problem if you wish to have the same coderef triggered from several
186             different attributes.
187              
188             This module adds a C<< $meta->triggered_attribute >> method to your
189             class' metaobject, which allows you to check which attribute has been
190             triggered.
191              
192             Yes, it works if you trigger one attribute from another attribute.
193              
194             Yes, it works in roles.
195              
196             Yes, it works with inheritance.
197              
198             =head1 BUGS
199              
200             Please report any bugs to
201             L<http://rt.cpan.org/Dist/Display.html?Queue=MooseX-WhatTheTrig>.
202              
203             =head1 SEE ALSO
204              
205             L<http://stackoverflow.com/questions/22306330/moose-trigger-caller>.
206              
207             =head1 AUTHOR
208              
209             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
210              
211             =head1 COPYRIGHT AND LICENCE
212              
213             This software is copyright (c) 2014 by Toby Inkster.
214              
215             This is free software; you can redistribute it and/or modify it under
216             the same terms as the Perl 5 programming language system itself.
217              
218             =head1 DISCLAIMER OF WARRANTIES
219              
220             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
221             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
222             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
223