File Coverage

blib/lib/Venus/Search.pm
Criterion Covered Total %
statement 100 100 100.0
branch 6 10 60.0
condition 23 48 47.9
subroutine 24 24 100.0
pod 14 15 93.3
total 167 197 84.7


line stmt bran cond sub pod time code
1             package Venus::Search;
2              
3 3     3   84 use 5.018;
  3         14  
4              
5 3     3   16 use strict;
  3         6  
  3         69  
6 3     3   13 use warnings;
  3         6  
  3         99  
7              
8 3     3   16 use Venus::Class 'attr', 'base', 'with';
  3         6  
  3         23  
9              
10             base 'Venus::Kind::Utility';
11              
12             with 'Venus::Role::Explainable';
13             with 'Venus::Role::Stashable';
14              
15             use overload (
16             '""' => 'explain',
17 1     1   5 'eq' => sub{"$_[0]" eq "$_[1]"},
18 1     1   5 'ne' => sub{"$_[0]" ne "$_[1]"},
19 1     1   3 'qr' => sub{qr{@{[quotemeta("$_[0]")]}}},
  1         5  
20 3         56 '~~' => 'explain',
21             fallback => 1,
22 3     3   23 );
  3         7  
23              
24             # ATTRIBUTES
25              
26             attr 'flags';
27             attr 'regexp';
28             attr 'string';
29              
30             # BUILDERS
31              
32             sub build_self {
33 25     25 0 55 my ($self, $data) = @_;
34              
35 25 50       97 $self->flags('') if !$self->flags;
36 25 50       76 $self->regexp(qr//) if !$self->regexp;
37 25 50       60 $self->string('') if !$self->string;
38              
39 25         50 return $self;
40             }
41              
42             # METHODS
43              
44             sub captures {
45 1     1 1 3 my ($self) = @_;
46              
47 1   33     4 my $evaluation = $self->stash('evaluation') || $self->evaluate;
48              
49 1         5 my $string = $self->initial;
50 1         4 my $last_match_start = $self->last_match_start;
51 1         3 my $last_match_end = $self->last_match_end;
52              
53 1         3 my $captures = [];
54              
55 1         8 for (my $i = 1; $i < @$last_match_end; $i++) {
56 1   50     5 my $start = $last_match_start->[$i] || 0;
57 1   50     4 my $end = $last_match_end->[$i] || 0;
58              
59 1         6 push @$captures, substr $string, $start, $end - $start;
60             }
61              
62 1 50       7 return wantarray ? (@$captures) : $captures;
63             }
64              
65             sub evaluate {
66 24     24 1 52 my ($self) = @_;
67              
68 24         42 my $captures = 0;
69 24         61 my $flags = $self->flags;
70 24         74 my @matches = ();
71 24         66 my $regexp = $self->regexp;
72 24         55 my $string = $self->string;
73 24         51 my $initial = "$string";
74              
75 24         69 local $@;
76 24   50 2   2106 eval join ';', (
  2         1095  
  2         1108  
  2         46  
77             '$captures = (' . '$string =~ m/$regexp/' . ($flags // '') . ')',
78             '@matches = ([@-], [@+], {%-})',
79             );
80              
81 24         117 my $error = $@;
82              
83 24 100       67 if ($error) {
84 1         12 $self->throw('error_on_evaluate', $error)->error;
85             }
86              
87 23         124 return $self->stash(evaluation => [
88             $regexp,
89             $string,
90             $captures,
91             @matches,
92             $initial,
93             ]);
94             }
95              
96             sub explain {
97 14     14 1 489 my ($self) = @_;
98              
99 14         60 return $self->get;
100             }
101              
102             sub get {
103 15     15 1 29 my ($self) = @_;
104              
105 15   66     52 my $evaluation = $self->stash('evaluation') || $self->evaluate;
106              
107 15         94 return $evaluation->[1];
108             }
109              
110             sub count {
111 1     1 1 4 my ($self) = @_;
112              
113 1   33     4 my $evaluation = $self->stash('evaluation') || $self->evaluate;
114              
115 1         6 return $evaluation->[2];
116             }
117              
118             sub initial {
119 5     5 1 17 my ($self) = @_;
120              
121 5   66     16 my $evaluation = $self->stash('evaluation') || $self->evaluate;
122              
123 5         21 return $evaluation->[6];
124             }
125              
126             sub last_match_end {
127 5     5 1 15 my ($self) = @_;
128              
129 5   66     14 my $evaluation = $self->stash('evaluation') || $self->evaluate;
130              
131 5         15 return $evaluation->[4];
132             }
133              
134             sub last_match_start {
135 5     5 1 12 my ($self) = @_;
136              
137 5   66     13 my $evaluation = $self->stash('evaluation') || $self->evaluate;
138              
139 5         15 return $evaluation->[3];
140             }
141              
142             sub matched {
143 1     1 1 4 my ($self) = @_;
144              
145 1   33     4 my $evaluation = $self->stash('evaluation') || $self->evaluate;
146              
147 1         8 my $string = $self->initial;
148 1         8 my $last_match_start = $self->last_match_start;
149 1         7 my $last_match_end = $self->last_match_end;
150              
151 1   50     7 my $start = $last_match_start->[0] || 0;
152 1   50     4 my $end = $last_match_end->[0] || 0;
153              
154 1         8 return substr $string, $start, $end - $start;
155             }
156              
157             sub named_captures {
158 2     2 1 5 my ($self) = @_;
159              
160 2   33     7 my $evaluation = $self->stash('evaluation') || $self->evaluate;
161              
162 2         11 return $evaluation->[5];
163             }
164              
165             sub prematched {
166 1     1 1 3 my ($self) = @_;
167              
168 1   33     4 my $evaluation = $self->stash('evaluation') || $self->evaluate;
169              
170 1         6 my $string = $self->initial;
171 1         6 my $last_match_start = $self->last_match_start;
172 1         5 my $last_match_end = $self->last_match_end;
173              
174 1   50     6 my $start = $last_match_start->[0] || 0;
175 1   50     5 my $end = $last_match_end->[0] || 0;
176              
177 1         7 return substr $string, 0, $start;
178             }
179              
180             sub postmatched {
181 1     1 1 3 my ($self) = @_;
182              
183 1   33     5 my $evaluation = $self->stash('evaluation') || $self->evaluate;
184              
185 1         7 my $string = $self->initial;
186 1         4 my $last_match_start = $self->last_match_start;
187 1         7 my $last_match_end = $self->last_match_end;
188              
189 1   50     7 my $start = $last_match_start->[0] || 0;
190 1   50     5 my $end = $last_match_end->[0] || 0;
191              
192 1         7 return substr $string, $end;
193             }
194              
195             sub set {
196 1     1 1 3 my ($self, $string) = @_;
197              
198 1         4 $self->string($string);
199              
200 1         3 my $evaluation = $self->evaluate;
201              
202 1         6 return $evaluation->[1];
203             }
204              
205             # ERRORS
206              
207             sub error_on_evaluate {
208 2     2 1 8 my ($self, $error) = @_;
209              
210             return {
211 2         9 name => 'on.evaluate',
212             message => $error,
213             };
214             }
215              
216             1;
217              
218              
219              
220             =head1 NAME
221              
222             Venus::Search - Search Class
223              
224             =cut
225              
226             =head1 ABSTRACT
227              
228             Search Class for Perl 5
229              
230             =cut
231              
232             =head1 SYNOPSIS
233              
234             package main;
235              
236             use Venus::Search;
237              
238             my $search = Venus::Search->new(
239             string => 'hello world',
240             regexp => '(hello)',
241             );
242              
243             # $search->captures;
244              
245             =cut
246              
247             =head1 DESCRIPTION
248              
249             This package provides methods for manipulating regexp search data.
250              
251             =cut
252              
253             =head1 ATTRIBUTES
254              
255             This package has the following attributes:
256              
257             =cut
258              
259             =head2 flags
260              
261             flags(Str)
262              
263             This attribute is read-write, accepts C<(Str)> values, is optional, and defaults to C<''>.
264              
265             =cut
266              
267             =head2 regexp
268              
269             regexp(Regexp)
270              
271             This attribute is read-write, accepts C<(Regexp)> values, is optional, and defaults to C.
272              
273             =cut
274              
275             =head2 string
276              
277             string(Str)
278              
279             This attribute is read-write, accepts C<(Str)> values, is optional, and defaults to C<''>.
280              
281             =cut
282              
283             =head1 INHERITS
284              
285             This package inherits behaviors from:
286              
287             L
288              
289             =cut
290              
291             =head1 INTEGRATES
292              
293             This package integrates behaviors from:
294              
295             L
296              
297             L
298              
299             =cut
300              
301             =head1 METHODS
302              
303             This package provides the following methods:
304              
305             =cut
306              
307             =head2 captures
308              
309             captures() (ArrayRef)
310              
311             The captures method returns the capture groups from the result object which
312             contains information about the results of the regular expression operation.
313             This method can return a list of values in list-context.
314              
315             I>
316              
317             =over 4
318              
319             =item captures example 1
320              
321             # given: synopsis;
322              
323             my $captures = $search->captures;
324              
325             # ["hello"]
326              
327             =back
328              
329             =cut
330              
331             =head2 count
332              
333             count() (Num)
334              
335             The count method returns the number of matches found in the result object which
336             contains information about the results of the regular expression operation.
337              
338             I>
339              
340             =over 4
341              
342             =item count example 1
343              
344             # given: synopsis;
345              
346             my $count = $search->count;
347              
348             # 1
349              
350             =back
351              
352             =cut
353              
354             =head2 evaluate
355              
356             evaluate() (ArrayRef)
357              
358             The evaluate method performs the regular expression operation and returns an
359             arrayref representation of the results.
360              
361             I>
362              
363             =over 4
364              
365             =item evaluate example 1
366              
367             # given: synopsis;
368              
369             my $evaluate = $search->evaluate;
370              
371             # ["(hello)", "hello world", 1, [0, 0], [5, 5], {}, "hello world"]
372              
373             =back
374              
375             =over 4
376              
377             =item evaluate example 2
378              
379             package main;
380              
381             use Venus::Search;
382              
383             my $search = Venus::Search->new(
384             string => 'hello world',
385             regexp => 'hello:)',
386             );
387              
388             my $evaluate = $search->evaluate;
389              
390             # Exception! (isa Venus::Search::Error) (see error_on_evaluate)
391              
392             =back
393              
394             =cut
395              
396             =head2 explain
397              
398             explain() (Str)
399              
400             The explain method returns the subject of the regular expression operation and
401             is used in stringification operations.
402              
403             I>
404              
405             =over 4
406              
407             =item explain example 1
408              
409             # given: synopsis;
410              
411             my $explain = $search->explain;
412              
413             # "hello world"
414              
415             =back
416              
417             =cut
418              
419             =head2 get
420              
421             get() (Str)
422              
423             The get method returns the subject of the regular expression operation.
424              
425             I>
426              
427             =over 4
428              
429             =item get example 1
430              
431             # given: synopsis;
432              
433             my $get = $search->get;
434              
435             # "hello world"
436              
437             =back
438              
439             =cut
440              
441             =head2 initial
442              
443             initial() (Str)
444              
445             The initial method returns the unaltered string from the result object which
446             contains information about the results of the regular expression operation.
447              
448             I>
449              
450             =over 4
451              
452             =item initial example 1
453              
454             # given: synopsis;
455              
456             my $initial = $search->initial;
457              
458             # "hello world"
459              
460             =back
461              
462             =cut
463              
464             =head2 last_match_end
465              
466             last_match_end() (Maybe[ArrayRef[Int]])
467              
468             The last_match_end method returns an array of offset positions into the string
469             where the capture(s) stopped matching from the result object which contains
470             information about the results of the regular expression operation.
471              
472             I>
473              
474             =over 4
475              
476             =item last_match_end example 1
477              
478             # given: synopsis;
479              
480             my $last_match_end = $search->last_match_end;
481              
482             # [5, 5]
483              
484             =back
485              
486             =cut
487              
488             =head2 last_match_start
489              
490             last_match_start() (Maybe[ArrayRef[Int]])
491              
492             The last_match_start method returns an array of offset positions into the
493             string where the capture(s) matched from the result object which contains
494             information about the results of the regular expression operation.
495              
496             I>
497              
498             =over 4
499              
500             =item last_match_start example 1
501              
502             # given: synopsis;
503              
504             my $last_match_start = $search->last_match_start;
505              
506             # [0, 0]
507              
508             =back
509              
510             =cut
511              
512             =head2 matched
513              
514             matched() (Maybe[Str])
515              
516             The matched method returns the portion of the string that matched from the
517             result object which contains information about the results of the regular
518             expression operation.
519              
520             I>
521              
522             =over 4
523              
524             =item matched example 1
525              
526             # given: synopsis;
527              
528             my $matched = $search->matched;
529              
530             # "hello"
531              
532             =back
533              
534             =cut
535              
536             =head2 named_captures
537              
538             named_captures() (HashRef)
539              
540             The named_captures method returns a hash containing the requested named regular
541             expressions and captured string pairs from the result object which contains
542             information about the results of the regular expression operation.
543              
544             I>
545              
546             =over 4
547              
548             =item named_captures example 1
549              
550             # given: synopsis;
551              
552             my $named_captures = $search->named_captures;
553              
554             # {}
555              
556             =back
557              
558             =over 4
559              
560             =item named_captures example 2
561              
562             package main;
563              
564             use Venus::Search;
565              
566             my $search = Venus::Search->new(
567             string => 'hello world',
568             regexp => '(?world)',
569             );
570              
571             my $named_captures = $search->named_captures;
572              
573             # { locale => ["world"] }
574              
575             =back
576              
577             =cut
578              
579             =head2 postmatched
580              
581             postmatched() (Maybe[Str])
582              
583             The postmatched method returns the portion of the string after the regular
584             expression matched from the result object which contains information about the
585             results of the regular expression operation.
586              
587             I>
588              
589             =over 4
590              
591             =item postmatched example 1
592              
593             # given: synopsis;
594              
595             my $postmatched = $search->postmatched;
596              
597             # " world"
598              
599             =back
600              
601             =cut
602              
603             =head2 prematched
604              
605             prematched() (Maybe[Str])
606              
607             The prematched method returns the portion of the string before the regular
608             expression matched from the result object which contains information about the
609             results of the regular expression operation.
610              
611             I>
612              
613             =over 4
614              
615             =item prematched example 1
616              
617             # given: synopsis;
618              
619             my $prematched = $search->prematched;
620              
621             # ""
622              
623             =back
624              
625             =cut
626              
627             =head2 set
628              
629             set(Str $string) (Str)
630              
631             The set method sets the subject of the regular expression operation.
632              
633             I>
634              
635             =over 4
636              
637             =item set example 1
638              
639             # given: synopsis;
640              
641             my $set = $search->set('hello universe');
642              
643             # "hello universe"
644              
645             =back
646              
647             =cut
648              
649             =head1 ERRORS
650              
651             This package may raise the following errors:
652              
653             =cut
654              
655             =over 4
656              
657             =item error: C
658              
659             This package may raise an error_on_evaluate exception.
660              
661             B
662              
663             # given: synopsis;
664              
665             my @args = ("Exception!");
666              
667             my $error = $search->throw('error_on_evaluate', @args)->catch('error');
668              
669             # my $name = $error->name;
670              
671             # "on_evaluate"
672              
673             # my $message = $error->message;
674              
675             # "Exception!"
676              
677             =back
678              
679             =head1 OPERATORS
680              
681             This package overloads the following operators:
682              
683             =cut
684              
685             =over 4
686              
687             =item operation: C<(.)>
688              
689             This package overloads the C<.> operator.
690              
691             B
692              
693             # given: synopsis;
694              
695             my $result = $search . ', welcome';
696              
697             # "hello world, welcome"
698              
699             =back
700              
701             =over 4
702              
703             =item operation: C<(eq)>
704              
705             This package overloads the C operator.
706              
707             B
708              
709             # given: synopsis;
710              
711             my $result = $search eq 'hello world';
712              
713             # 1
714              
715             =back
716              
717             =over 4
718              
719             =item operation: C<(ne)>
720              
721             This package overloads the C operator.
722              
723             B
724              
725             # given: synopsis;
726              
727             my $result = $search ne 'Hello world';
728              
729             # 1
730              
731             =back
732              
733             =over 4
734              
735             =item operation: C<(qr)>
736              
737             This package overloads the C operator.
738              
739             B
740              
741             # given: synopsis;
742              
743             my $result = 'hello world, welcome' =~ qr/$search/;
744              
745             # 1
746              
747             =back
748              
749             =over 4
750              
751             =item operation: C<("")>
752              
753             This package overloads the C<""> operator.
754              
755             B
756              
757             # given: synopsis;
758              
759             my $result = "$search";
760              
761             # "hello world"
762              
763             B
764              
765             # given: synopsis;
766              
767             my $result = "$search, $search";
768              
769             # "hello world, hello world"
770              
771             =back
772              
773             =over 4
774              
775             =item operation: C<(~~)>
776              
777             This package overloads the C<~~> operator.
778              
779             B
780              
781             # given: synopsis;
782              
783             my $result = $search ~~ 'hello world';
784              
785             # 1
786              
787             =back
788              
789             =head1 AUTHORS
790              
791             Awncorp, C
792              
793             =cut
794              
795             =head1 LICENSE
796              
797             Copyright (C) 2000, Al Newkirk.
798              
799             This program is free software, you can redistribute it and/or modify it under
800             the terms of the Apache license version 2.0.
801              
802             =cut