File Coverage

blib/lib/Lingua/Awkwords.pm
Criterion Covered Total %
statement 72 73 98.6
branch 22 24 91.6
condition n/a
subroutine 15 15 100.0
pod 7 7 100.0
total 116 119 97.4


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # randomly generates outputs from a given pattern
4              
5             package Lingua::Awkwords;
6              
7 2     2   100537 use strict;
  2         12  
  2         50  
8 2     2   9 use warnings;
  2         3  
  2         101  
9              
10             require Exporter;
11             our @ISA = qw(Exporter);
12             our @EXPORT_OK = qw/&percentize &set_filter &weights2str &weights_from/;
13              
14 2     2   10 use Carp qw(croak);
  2         4  
  2         99  
15 2     2   361 use Lingua::Awkwords::Parser;
  2         17  
  2         51  
16 2     2   10 use Moo;
  2         4  
  2         9  
17 2     2   605 use namespace::clean;
  2         4  
  2         11  
18              
19             our $VERSION = '0.08';
20              
21             has pattern => (
22             is => 'rw',
23             trigger => sub {
24             my ( $self, $pat ) = @_;
25             $self->_set_tree( Lingua::Awkwords::Parser->new->from_string($pat) );
26             },
27             );
28             has tree => ( is => 'rwp' );
29              
30             ########################################################################
31             #
32             # FUNCTIONS
33             #
34             # TODO these probably should go in a ::Util module?
35              
36             # utility routine that makes percentages of the presumably numeric
37             # values of the given hash reference
38             sub percentize {
39 1     1 1 4823 my ($href) = @_;
40 1         3 my $sum = 0;
41 1         2 my $min = ~0;
42 1         3 for my $v ( values %$href ) {
43 4         6 $sum += $v;
44 4 100       9 $min = $v if $v < $min;
45             }
46 1 50       3 croak "sum of values cannot be 0" if $sum == 0;
47 1         4 for my $v ( values %$href ) {
48 4         8 $v = $v / $sum * 100;
49             }
50             }
51              
52             # utility routine for use with ->walk
53             sub set_filter {
54 3     3 1 343 my $filter = shift;
55             return sub {
56 19     19   21 my $self = shift;
57 19 100       65 $self->filter_with($filter) if $self->can('filter_with');
58 3         18 };
59             }
60              
61             sub weights2str {
62 1     1 1 4 my ($hr) = @_;
63             return join '/',
64 1 100       6 map { $hr->{$_} == 1 ? $_ : join( '*', $_, $hr->{$_} ) } sort keys %$hr;
  9         26  
65             }
66              
67             sub weights_from {
68 3     3 1 6766 my ($input) = @_;
69              
70 3         7 my $type = ref $input;
71 3         5 my $fh;
72              
73 3 100       22 if ( $type eq '' ) {
    50          
74 2     1   51 open $fh, '<', \$input;
  1         7  
  1         2  
  1         6  
75             } elsif ( $type eq 'GLOB' ) {
76 1         4 $fh = $input;
77             } else {
78 0         0 croak "unknown input type";
79             }
80              
81 3         874 my ( %first, %mid, %last, %all );
82              
83 3         31 while ( readline $fh ) {
84 3         8 chomp;
85             LOOP: {
86 3 100       3 redo LOOP if /\G\s+/cg;
  88         155  
87             # various \b{...} forms detailed in perlrebackslash may be
88             # better for word boundaries though require perl 5.22 or up
89 72 100       113 if (m/\G\b(.)/cg) {
90 19         30 $first{$1}++;
91 19         25 $all{$1}++;
92 19         20 redo LOOP;
93             }
94 53 100       74 if (m/\G(.)\b/cg) {
95 19         28 $last{$1}++;
96 19         21 $all{$1}++;
97 19         21 redo LOOP;
98             }
99 34 100       71 if (m/\G\B(.)/cg) {
100 31         42 $mid{$1}++;
101 31         37 $all{$1}++;
102 31         31 redo LOOP;
103             }
104             }
105             }
106              
107 3         29 return \%first, \%mid, \%last, \%all;
108             }
109              
110             ########################################################################
111             #
112             # METHODS
113              
114             # avoids need to say
115             # use Lingua::Awkwords::Parser;
116             # ... = Lingua::Awkwords::Parser->new->from_string(q{ ...
117             # in the calling code
118             sub parse_string {
119 2     2 1 391 my ( $self_or_class, $str ) = @_;
120 2         6 return Lingua::Awkwords::Parser->new->from_string($str);
121             }
122              
123             sub render {
124 3     3 1 1362 my ($self) = @_;
125 3         9 my $tree = $self->tree;
126 3 100       24 croak "no pattern supplied" if !defined $tree;
127 2         6 return $tree->render;
128             }
129              
130             sub walk {
131 3     3 1 904 my ( $self, $callback ) = @_;
132 3         7 my $tree = $self->tree;
133 3 100       16 croak "no pattern supplied" if !defined $tree;
134 2         7 $tree->walk($callback);
135 2         2 return;
136             }
137              
138             1;
139             __END__