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   101928 use strict;
  2         11  
  2         56  
8 2     2   9 use warnings;
  2         3  
  2         95  
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         3  
  2         95  
15 2     2   354 use Lingua::Awkwords::Parser;
  2         4  
  2         48  
16 2     2   12 use Moo;
  2         2  
  2         9  
17 2     2   582 use namespace::clean;
  2         2  
  2         11  
18              
19             our $VERSION = '0.10';
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 4758 my ($href) = @_;
40 1         2 my $sum = 0;
41 1         2 my $min = ~0;
42 1         3 for my $v (values %$href) {
43 4         5 $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         2 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 353 my $filter = shift;
55             return sub {
56 19     19   23 my $self = shift;
57 19 100       67 $self->filter_with($filter) if $self->can('filter_with');
58 3         18 };
59             }
60              
61             sub weights2str {
62 1     1 1 3 my ($hr) = @_;
63             return join '/',
64 1 100       15 map { $hr->{$_} == 1 ? $_ : join('*', $_, $hr->{$_}) } sort keys %$hr;
  9         27  
65             }
66              
67             sub weights_from {
68 3     3 1 6592 my ($input) = @_;
69              
70 3         7 my $type = ref $input;
71 3         4 my $fh;
72              
73 3 100       10 if ($type eq '') {
    50          
74 2     1   57 open $fh, '<', \$input;
  1         7  
  1         13  
  1         6  
75             } elsif ($type eq 'GLOB') {
76 1         2 $fh = $input;
77             } else {
78 0         0 croak "unknown input type";
79             }
80              
81 3         790 my (%first, %mid, %last, %all);
82              
83 3         31 while (readline $fh) {
84 3         6 chomp;
85             LOOP: {
86 3 100       4 redo LOOP if /\G\s+/cg;
  88         147  
87             # various \b{...} forms detailed in perlrebackslash may be
88             # better for word boundaries though require perl 5.22 or up
89 72 100       125 if (m/\G\b(.)/cg) {
90 19         31 $first{$1}++;
91 19         24 $all{$1}++;
92 19         23 redo LOOP;
93             }
94 53 100       83 if (m/\G(.)\b/cg) {
95 19         27 $last{$1}++;
96 19         24 $all{$1}++;
97 19         20 redo LOOP;
98             }
99 34 100       68 if (m/\G\B(.)/cg) {
100 31         41 $mid{$1}++;
101 31         40 $all{$1}++;
102 31         37 redo LOOP;
103             }
104             }
105             }
106              
107 3         19 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 378 my ($self_or_class, $str) = @_;
120 2         8 return Lingua::Awkwords::Parser->new->from_string($str);
121             }
122              
123             sub render {
124 3     3 1 1300 my ($self) = @_;
125 3         9 my $tree = $self->tree;
126 3 100       23 croak "no pattern supplied" if !defined $tree;
127 2         6 return $tree->render;
128             }
129              
130             sub walk {
131 3     3 1 852 my ($self, $callback) = @_;
132 3         8 my $tree = $self->tree;
133 3 100       16 croak "no pattern supplied" if !defined $tree;
134 2         8 $tree->walk($callback);
135 2         3 return;
136             }
137              
138             1;
139             __END__