File Coverage

blib/lib/Sub/HandlesVia.pm
Criterion Covered Total %
statement 62 62 100.0
branch 20 30 66.6
condition 32 48 66.6
subroutine 12 12 100.0
pod 0 1 0.0
total 126 153 82.3


line stmt bran cond sub pod time code
1 93     93   13483380 use 5.008;
  93         813  
2 93     93   573 use strict;
  93         222  
  93         2103  
3 93     93   542 use warnings;
  93         212  
  93         3970  
4              
5              
6             use Exporter::Shiny qw( delegations );
7 93     93   40138  
  93         372765  
  93         638  
8             our $AUTHORITY = 'cpan:TOBYINK';
9             our $VERSION = '0.045';
10              
11             my ($me, $name, $args, $globals) = (shift, @_);
12            
13 4     4   346 my $target = $globals->{into};
14             !defined $target and die;
15 4         13 ref $target and die;
16 4 50       19  
17 4 50       16 my $toolkit = $me->detect_toolkit($target);
18             return sub { $toolkit->install_delegations(target => $target, @_) };
19 4         24 }
20 4     6   41  
  6         4026  
21             my ($me, $globals) = (shift, @_);
22              
23             my $target = $globals->{into};
24 295     295   18844437 !defined $target and die;
25             ref $target and die;
26 295         922  
27 295 50       2628 my $toolkit = $me->detect_toolkit($target);
28 295 50       2558 $toolkit->setup_for($target) if $toolkit->can('setup_for');
29             }
30 295         1059  
31 295 100       3453 my $toolkit = sprintf(
32             '%s::Toolkit::%s',
33             __PACKAGE__,
34             shift->_detect_framework(@_),
35 299     299 0 1334 );
36             eval "require $toolkit" or Exporter::Tiny::_croak($@);
37             return $toolkit;
38             }
39              
40 299 50       20379 my ($me, $target) = (shift, @_);
41 299         1682
42             # Need to ask Role::Tiny too because Moo::Role will pretend
43             # that Moose::Role and Mouse::Role roles are Moo::Role roles!
44             #
45 300     300   1073 if ($INC{'Moo/Role.pm'}
46             and Role::Tiny->is_role($target)
47             and Moo::Role->is_role($target)) {
48             return 'Moo';
49             }
50 300 100 100     1647
      66        
51             if ($INC{'Moo.pm'}
52             and $Moo::MAKERS{$target}
53 3         146 and $Moo::MAKERS{$target}{is_class}) {
54             return 'Moo';
55             }
56 297 50 66     2298
      33        
57             if ($INC{'Moose/Role.pm'}
58             and $target->can('meta')
59 101         704 and $target->meta->isa('Moose::Meta::Role')) {
60             return 'Moose';
61             }
62 196 100 66     1981
      100        
63             if ($INC{'Moose.pm'}
64             and $target->can('meta')
65 3         111 and $target->meta->isa('Moose::Meta::Class')) {
66             return 'Moose';
67             }
68 193 50 66     3328  
      66        
69             if ($INC{'Mouse/Role.pm'}
70             and $target->can('meta')
71 86         2179 and $target->meta->isa('Mouse::Meta::Role')) {
72             return 'Mouse';
73             }
74 107 100 66     1787
      100        
75             if ($INC{'Mouse.pm'}
76             and $target->can('meta')
77 4         148 and $target->meta->isa('Mouse::Meta::Class')) {
78             return 'Mouse';
79             }
80 103 50 66     2469
      66        
81             {
82             no warnings;
83 85         1749 if ($INC{'Object/Pad.pm'}
84             and 'Object::Pad'->VERSION ge 0.67
85             and do { require Object::Pad::MOP::Class; 1 }
86             and eval { Object::Pad::MOP::Class->for_class($target) } ) {
87 93     93   47459 require Scalar::Util;
  93         276  
  93         14896  
88 18 50 66     104 my $META = Object::Pad::MOP::Class->for_class($target);
      66        
      33        
89             return 'ObjectPad'
90 2         13 if Scalar::Util::blessed($META) && $META->isa('Object::Pad::MOP::Class');
  2         8  
91 2         13 }
92 2         338 }
93 2         28
94 2 50 33     172 {
95             no strict 'refs';
96             no warnings 'once';
97             if ( ${"$target\::USES_MITE"} ) {
98             return 'Mite';
99             }
100 93     93   748 }
  93         248  
  93         3534  
  18         30  
  16         25  
101 93     93   600
  93         1525  
  93         10871  
102 16 100       26 return 'Plain';
  16         89  
103 10         68 }
104              
105             1;
106              
107 6         37  
108             =pod
109              
110             =encoding utf-8
111              
112             =head1 NAME
113              
114             Sub::HandlesVia - alternative handles_via implementation
115              
116             =head1 SYNOPSIS
117              
118             package Kitchen {
119             use Moo;
120             use Sub::HandlesVia;
121             use Types::Standard qw( ArrayRef Str );
122            
123             has food => (
124             is => 'ro',
125             isa => ArrayRef[Str],
126             handles_via => 'Array',
127             default => sub { [] },
128             handles => {
129             'add_food' => 'push',
130             'find_food' => 'grep',
131             },
132             );
133             }
134              
135             my $kitchen = Kitchen->new;
136             $kitchen->add_food('Bacon');
137             $kitchen->add_food('Eggs');
138             $kitchen->add_food('Sausages');
139             $kitchen->add_food('Beans');
140            
141             my @foods = $kitchen->find_food(sub { /^B/i });
142              
143             =head1 DESCRIPTION
144              
145             If you've used L<Moose>'s native attribute traits, or L<MooX::HandlesVia>
146             before, you should have a fairly good idea what this does.
147              
148             Why re-invent the wheel? Well, this is an implementation that should work
149             okay with Moo, Moose, Mouse, and any other OO toolkit you throw at it.
150             One ring to rule them all, so to speak.
151              
152             For details of how to use it, see the manual.
153              
154             =over
155              
156             =item L<Sub::HandlesVia::Manual::WithMoo>
157              
158             How to use Sub::HandlesVia with L<Moo> and L<Moo::Role>.
159              
160             =item L<Sub::HandlesVia::Manual::WithMoose>
161              
162             How to use Sub::HandlesVia with L<Moose> and L<Moose::Role>.
163              
164             =item L<Sub::HandlesVia::Manual::WithMouse>
165              
166             How to use Sub::HandlesVia with L<Mouse> and L<Mouse::Role>.
167              
168             =item L<Sub::HandlesVia::Manual::WithMite>
169              
170             How to use Sub::HandlesVia with L<Mite>.
171              
172             =item L<Sub::HandlesVia::Manual::WithClassTiny>
173              
174             How to use Sub::HandlesVia with L<Class::Tiny>.
175              
176             =item L<Sub::HandlesVia::Manual::WithObjectPad>
177              
178             How to use Sub::HandlesVia with L<Object::Pad> classes.
179              
180             =item L<Sub::HandlesVia::Manual::WithGeneric>
181              
182             How to use Sub::HandlesVia with other OO toolkits, and hand-written
183             Perl classes.
184              
185             =back
186              
187             Note: as Sub::HandlesVia needs to detect which toolkit you are using, and
188             often needs to detect whether your package is a class or a role, it needs
189             to be loaded I<after> Moo/Moose/Mouse/etc. Your C<< use Moo >> or
190             C<< use Moose::Role >> or whatever needs to be I<before> your
191             C<< use Sub::HandlesVia >>.
192              
193             =head1 BUGS
194              
195             Please report any bugs to
196             L<https://github.com/tobyink/p5-sub-handlesvia/issues>.
197              
198             (There are known bugs for Moose native types that do coercion.)
199              
200             =head1 SEE ALSO
201              
202             Guides for use with different OO toolkits:
203             L<Sub::HandlesVia::Manual::WithMoo>,
204             L<Sub::HandlesVia::Manual::WithMoose>,
205             L<Sub::HandlesVia::Manual::WithMouse>,
206             L<Sub::HandlesVia::Manual::WithMite>,
207             L<Sub::HandlesVia::Manual::WithClassTiny>,
208             L<Sub::HandlesVia::Manual::WithObjectPad>,
209             L<Sub::HandlesVia::Manual::WithGeneric>.
210              
211             Documentation for delegatable methods:
212             L<Sub::HandlesVia::HandlerLibrary::Array>,
213             L<Sub::HandlesVia::HandlerLibrary::Blessed>,
214             L<Sub::HandlesVia::HandlerLibrary::Bool>,
215             L<Sub::HandlesVia::HandlerLibrary::Code>,
216             L<Sub::HandlesVia::HandlerLibrary::Counter>,
217             L<Sub::HandlesVia::HandlerLibrary::Hash>,
218             L<Sub::HandlesVia::HandlerLibrary::Number>,
219             L<Sub::HandlesVia::HandlerLibrary::Scalar>, and
220             L<Sub::HandlesVia::HandlerLibrary::String>.
221              
222             Other implementations of the same concept:
223             L<Moose::Meta::Attribute::Native>, L<MouseX::NativeTraits>, and
224             L<MooX::HandlesVia> with L<Data::Perl>.
225              
226             Comparison of those: L<Sub::HandlesVia::Manual::Comparison>
227              
228             L<Sub::HandlesVia::Declare> is a helper for declaring Sub::HandlesVia
229             delegations at compile-time, useful for L<Object::Pad> and (to a lesser
230             extent) L<Class::Tiny>.
231              
232             =head1 AUTHOR
233              
234             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
235              
236             =head1 COPYRIGHT AND LICENCE
237              
238             This software is copyright (c) 2020, 2022 by Toby Inkster.
239              
240             This is free software; you can redistribute it and/or modify it under
241             the same terms as the Perl 5 programming language system itself.
242              
243             =head1 DISCLAIMER OF WARRANTIES
244              
245             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
246             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
247             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
248