File Coverage

blib/lib/Sub/HandlesVia/HandlerLibrary/String.pm
Criterion Covered Total %
statement 71 72 98.6
branch 2 2 100.0
condition 2 3 66.6
subroutine 43 44 97.7
pod 21 21 100.0
total 139 142 97.8


line stmt bran cond sub pod time code
1 11     11   718 use 5.008;
  11         46  
2 11     11   60 use strict;
  11         20  
  11         304  
3 11     11   67 use warnings;
  11         26  
  11         711  
4              
5              
6             our $AUTHORITY = 'cpan:TOBYINK';
7             our $VERSION = '0.045';
8              
9             use Sub::HandlesVia::HandlerLibrary;
10 11     11   3768 our @ISA = 'Sub::HandlesVia::HandlerLibrary';
  11         30  
  11         556  
11              
12             use Sub::HandlesVia::Handler qw( handler );
13 11     11   99 use Types::Standard qw( Optional Str CodeRef RegexpRef Int Any Item Defined );
  11         23  
  11         90  
14 11     11   1047  
  11         27  
  11         60  
15             our @METHODS = qw(
16             set get inc append prepend chop chomp clear reset
17             length substr replace replace_globally uc lc fc
18             starts_with ends_with contains match cmp eq ne gt lt ge le
19             starts_with_i ends_with_i contains_i match_i cmpi eqi nei gti lti gei lei
20             );
21              
22             my $fold = ( $] >= 5.016 ) ? 'CORE::fc' : 'lc';
23              
24             my ($me, $type) = @_;
25             if ($type == Str or $type == Defined) {
26 132     132   307 return {
27 132 100 66     459 trust_mutated => 'always',
28             };
29 84         6493 }
30             return $me->SUPER::_type_inspector($type);
31             }
32 48         22799  
33             handler
34             name => 'String:set',
35             args => 1,
36             signature => [Str],
37             template => '« $ARG »',
38             lvalue_template => '$GET = $ARG',
39             usage => '$value',
40             documentation => "Sets the string to a new value.",
41             _examples => sub {
42             my ( $class, $attr, $method ) = @_;
43             return join "",
44             " my \$object = $class\->new( $attr => 'foo' );\n",
45 1     1   73 " \$object->$method\( 'bar' );\n",
46 1         7 " say \$object->$attr; ## ==> 'bar'\n",
47             "\n";
48             },
49             }
50              
51             handler
52 4     4 1 36 name => 'String:get',
53             args => 0,
54             template => '$GET',
55             documentation => "Gets the current value of the string.",
56             _examples => sub {
57             my ( $class, $attr, $method ) = @_;
58             return join "",
59             " my \$object = $class\->new( $attr => 'foo' );\n",
60             " say \$object->$method; ## ==> 'foo'\n",
61 1     1   64 "\n";
62 1         6 },
63             }
64              
65             handler
66             name => 'String:inc',
67 3     3 1 25 args => 0,
68             template => '« do { my $shv_tmp = $GET; ++$shv_tmp } »',
69             lvalue_template => '++$GET',
70 35     35 1 189 additional_validation => 'no incoming values',
71             documentation => "Performs C<< ++ >> on the string.",
72             }
73              
74             handler
75             name => 'String:append',
76             args => 1,
77             signature => [Str],
78             template => '« $GET . $ARG »',
79             lvalue_template => '$GET .= $ARG',
80             usage => '$tail',
81             documentation => "Appends another string to the end of the current string and updates the attribute.",
82             _examples => sub {
83             my ( $class, $attr, $method ) = @_;
84             return join "",
85             " my \$object = $class\->new( $attr => 'foo' );\n",
86             " \$object->$method( 'bar' );\n",
87             " say \$object->$attr; ## ==> 'foobar'\n",
88             "\n";
89 1     1   66 },
90 1         7 }
91              
92             handler
93             args => 1,
94             name => 'String:prepend',
95             signature => [Str],
96 70     70 1 308 template => '« $ARG . $GET »',
97             usage => '$head',
98             documentation => "Prepends another string to the start of the current string and updates the attribute.",
99             _examples => sub {
100             my ( $class, $attr, $method ) = @_;
101             return join "",
102             " my \$object = $class\->new( $attr => 'foo' );\n",
103             " \$object->$method( 'bar' );\n",
104             " say \$object->$attr; ## ==> 'barfoo'\n",
105             "\n";
106             },
107 1     1   63 }
108 1         6  
109             handler
110             name => 'String:replace',
111             args => 2,
112             signature => [ Str|RegexpRef, Str|CodeRef ],
113             usage => '$regexp, $replacement',
114 67     67 1 626 template => sprintf(
115             'my $shv_tmp = $GET; if (%s) { my $shv_callback = $ARG[2]; $shv_tmp =~ s/$ARG[1]/$shv_callback->()/e } else { $shv_tmp =~ s/$ARG[1]/$ARG[2]/ } «$shv_tmp»',
116             CodeRef->inline_check('$ARG[2]'),
117             ),
118             lvalue_template => sprintf(
119             'if (%s) { my $shv_callback = $ARG[2]; $GET =~ s/$ARG[1]/$shv_callback->()/e } else { $GET =~ s/$ARG[1]/$ARG[2]/ } $GET',
120             CodeRef->inline_check('$ARG[2]'),
121             ),
122             documentation => "Replaces the first regexp match within the string with the replacement string.",
123             _examples => sub {
124             my ( $class, $attr, $method ) = @_;
125             return join "",
126             " my \$object = $class\->new( $attr => 'foo' );\n",
127             " \$object->$method( 'o' => 'a' );\n",
128             " say \$object->$attr; ## ==> 'fao'\n",
129             "\n",
130             " my \$object2 = $class\->new( $attr => 'foo' );\n",
131             " \$object2->$method( qr/O/i => sub { return 'e' } );\n",
132 1     1   75 " say \$object2->$attr; ## ==> 'feo'\n",
133 1         19 "\n";
134             },
135             }
136              
137             handler
138             name => 'String:replace_globally',
139             args => 2,
140             signature => [ Str|RegexpRef, Str|CodeRef ],
141             usage => '$regexp, $replacement',
142             template => sprintf(
143 67     67 1 361 'my $shv_tmp = $GET; if (%s) { my $shv_callback = $ARG[2]; $shv_tmp =~ s/$ARG[1]/$shv_callback->()/eg } else { $shv_tmp =~ s/$ARG[1]/$ARG[2]/g } «$shv_tmp»',
144             CodeRef->inline_check('$ARG[2]'),
145             ),
146             lvalue_template => sprintf(
147             'if (%s) { my $shv_callback = $ARG[2]; $GET =~ s/$ARG[1]/$shv_callback->()/eg } else { $GET =~ s/$ARG[1]/$ARG[2]/g } $GET',
148             CodeRef->inline_check('$ARG[2]'),
149             ),
150             documentation => "Replaces the all regexp matches within the string with the replacement string.",
151             _examples => sub {
152             my ( $class, $attr, $method ) = @_;
153             return join "",
154             " my \$object = $class\->new( $attr => 'foo' );\n",
155             " \$object->$method( 'o' => 'a' );\n",
156             " say \$object->$attr; ## ==> 'faa'\n",
157             "\n",
158             " my \$object2 = $class\->new( $attr => 'foo' );\n",
159             " \$object2->$method( qr/O/i => sub { return 'e' } );\n",
160             " say \$object2->$attr; ## ==> 'fee'\n",
161 1     1   64 "\n";
162 1         9 },
163             }
164              
165             handler
166             name => 'String:match',
167             args => 1,
168             signature => [ Str|RegexpRef ],
169             usage => '$regexp',
170             template => '$GET =~ /$ARG/',
171             documentation => "Returns true iff the string matches the regexp.",
172 3     3 1 72 _examples => sub {
173             my ( $class, $attr, $method ) = @_;
174             return join "",
175             " my \$object = $class\->new( $attr => 'foo' );\n",
176             " if ( \$object->$method\( '^f..\$' ) ) {\n",
177             " say 'matched!';\n",
178             " }\n",
179             "\n";
180             },
181             }
182              
183 1     1   66 handler
184 1         8 name => 'String:match_i',
185             args => 1,
186             signature => [ Str|RegexpRef ],
187             usage => '$regexp',
188             template => '$GET =~ /$ARG/i',
189             documentation => "Returns true iff the string matches the regexp case-insensitively.",
190             _examples => sub {
191 69     69 1 317 my ( $class, $attr, $method ) = @_;
192             return join "",
193             " my \$object = $class\->new( $attr => 'foo' );\n",
194             " if ( \$object->$method\( '^F..\$' ) ) {\n",
195             " say 'matched!';\n",
196             " }\n",
197             "\n";
198             },
199             }
200              
201             handler
202 1     1   66 name => 'String:starts_with',
203 1         8 args => 1,
204             signature => [ Str ],
205             usage => '$head',
206             template => 'substr($GET, 0, length $ARG) eq $ARG',
207             documentation => "Returns true iff the string starts with C<< \$head >>.",
208             }
209              
210 4     4 1 26 handler
211             name => 'String:starts_with_i',
212             args => 1,
213 4     4 1 40 signature => [ Str ],
214             usage => '$head',
215             template => sprintf( '%s(substr($GET, 0, length $ARG)) eq %s($ARG)', $fold, $fold ),
216             documentation => "Returns true iff the string starts with C<< \$head >> case-insensitvely.",
217             }
218              
219             handler
220             name => 'String:ends_with',
221             args => 1,
222             signature => [ Str ],
223 4     4 1 25 usage => '$tail',
224             template => 'substr($GET, -length $ARG) eq $ARG',
225             documentation => "Returns true iff the string ends with C<< \$tail >>.",
226             }
227              
228             handler
229             name => 'String:ends_with_i',
230             args => 1,
231             signature => [ Str ],
232             usage => '$tail',
233 4     4 1 21 template => sprintf( '%s(substr($GET, -length $ARG)) eq %s($ARG)', $fold, $fold ),
234             documentation => "Returns true iff the string ends with C<< \$tail >> case-insensitvely.",
235             }
236              
237             handler
238             name => 'String:contains',
239             args => 1,
240             signature => [ Str ],
241             usage => '$str',
242             template => 'index($GET, $ARG) != -1',
243 4     4 1 26 documentation => "Returns true iff the string contains C<< \$str >>.",
244             }
245              
246             handler
247             name => 'String:contains_i',
248             args => 1,
249             signature => [ Str ],
250             usage => '$str',
251             template => sprintf( 'index(%s($GET), %s($ARG)) != -1', $fold, $fold ),
252             documentation => "Returns true iff the string contains C<< \$str >> case-insensitvely.",
253 4     4 1 28 }
254              
255             handler
256             name => 'String:chop',
257             args => 0,
258             template => 'my $shv_return = chop(my $shv_tmp = $GET); «$shv_tmp»; $shv_return',
259             lvalue_template => 'chop($GET)',
260             additional_validation => 'no incoming values',
261             documentation => "Like C<chop> from L<perlfunc>.",
262             }
263 4     4 1 22  
264             handler
265             name => 'String:chomp',
266             args => 0,
267             template => 'my $shv_return = chomp(my $shv_tmp = $GET); «$shv_tmp»; $shv_return',
268             lvalue_template => 'chomp($GET)',
269             additional_validation => 'no incoming values',
270             documentation => "Like C<chomp> from L<perlfunc>.",
271             }
272              
273 35     35 1 160 handler
274             name => 'String:clear',
275             args => 0,
276             template => '«q()»',
277             additional_validation => 'no incoming values',
278             documentation => "Sets the string to the empty string.",
279             _examples => sub {
280             my ( $class, $attr, $method ) = @_;
281             return join "",
282             " my \$object = $class\->new( $attr => 'foo' );\n",
283 35     35 1 180 " \$object->$method;\n",
284             " say \$object->$attr; ## nothing\n",
285             "\n";
286             },
287             }
288              
289             handler
290             name => 'String:reset',
291             args => 0,
292             template => '« $DEFAULT »',
293             default_for_reset => sub { 'q()' },
294             documentation => 'Resets the attribute to its default value, or an empty string if it has no default.',
295             }
296              
297             handler
298             name => 'String:length',
299             args => 0,
300 1     1   64 template => 'length($GET)',
301 1         7 documentation => "Like C<length> from L<perlfunc>.",
302             _examples => sub {
303             my ( $class, $attr, $method ) = @_;
304             return join "",
305             " my \$object = $class\->new( $attr => 'foo' );\n",
306             " say \$object->$method; ## ==> 3\n",
307 35     35 1 300 "\n";
308             },
309             }
310              
311             handler
312             name => 'String:substr',
313             min_args => 1,
314 0     0   0 max_args => 3,
315 3     3 1 26 signature => [Int, Optional[Int], Optional[Str]],
316             usage => '$start, $length?, $replacement?',
317             template => 'if (#ARG==1) { substr($GET, $ARG[1]) } elsif (#ARG==2) { substr($GET, $ARG[1], $ARG[2]) } elsif (#ARG==3) { my $shv_tmp = $GET; my $shv_return = substr($shv_tmp, $ARG[1], $ARG[2], $ARG[3]); «$shv_tmp»; $shv_return } ',
318             lvalue_template => 'if (#ARG==1) { substr($GET, $ARG[1]) } elsif (#ARG==2) { substr($GET, $ARG[1], $ARG[2]) } elsif (#ARG==3) { substr($GET, $ARG[1], $ARG[2], $ARG[3]) } ',
319             documentation => "Like C<substr> from L<perlfunc>, but is not an lvalue.",
320             }
321              
322             for my $comparison ( qw/ cmp eq ne lt gt le ge / ) {
323             no strict 'refs';
324              
325 1     1   63 *$comparison = sub {
326 1         17 handler
327             name => "String:$comparison",
328             args => 1,
329             signature => [Str],
330             usage => '$str',
331 35     35 1 355 template => "\$GET $comparison \$ARG",
332             documentation => "Returns C<< \$object->attr $comparison \$str >>.",
333             };
334 131     131 1 693  
335             *{ $comparison . 'i' } = sub {
336             handler
337             name => "String:$comparison" . 'i',
338             args => 1,
339             signature => [Str],
340             usage => '$str',
341             template => "$fold(\$GET) $comparison $fold(\$ARG)",
342             documentation => "Returns C<< fc(\$object->attr) $comparison fc(\$str) >>. Uses C<lc> instead of C<fc> in versions of Perl older than 5.16.",
343             };
344             }
345              
346 11     11   57910 for my $mutation ( qw/ uc fc lc / ) {
  11         30  
  11         2249  
347             no strict 'refs';
348             my $mutationf = $mutation;
349 30     30   184 if ( $mutationf eq 'fc' ) {
350             $mutationf = $fold;
351             }
352             *$mutation = sub {
353             handler
354             name => "String:$mutation",
355             args => 0,
356             template => "$mutationf(\$GET)",
357             documentation => "Returns C<< $mutation(\$object->attr) >>.",
358             };
359 28     28   181 }
360              
361             1;