File Coverage

blib/lib/String/RewritePrefix.pm
Criterion Covered Total %
statement 37 37 100.0
branch 13 16 81.2
condition 1 2 50.0
subroutine 7 7 100.0
pod 1 1 100.0
total 59 63 93.6


line stmt bran cond sub pod time code
1 2     2   110162 use strict;
  2         21  
  2         52  
2 2     2   9 use warnings;
  2         3  
  2         79  
3             package String::RewritePrefix 0.009;
4              
5 2     2   10 use Carp ();
  2         4  
  2         78  
6             # ABSTRACT: rewrite strings based on a set of known prefixes
7              
8             # 0.972 allows \'method_name' form -- rjbs, 2010-10-25
9 2         11 use Sub::Exporter 0.972 -setup => {
10             exports => [ rewrite => \'_new_rewriter' ],
11 2     2   1033 };
  2         22671  
12              
13             #pod =head1 SYNOPSIS
14             #pod
15             #pod use String::RewritePrefix;
16             #pod my @to_load = String::RewritePrefix->rewrite(
17             #pod { '' => 'MyApp::', '+' => '' },
18             #pod qw(Plugin Mixin Addon +Corporate::Thinger),
19             #pod );
20             #pod
21             #pod # now you have:
22             #pod qw(MyApp::Plugin MyApp::Mixin MyApp::Addon Corporate::Thinger)
23             #pod
24             #pod You can also import a rewrite routine:
25             #pod
26             #pod use String::RewritePrefix rewrite => {
27             #pod -as => 'rewrite_dt_prefix',
28             #pod prefixes => { '' => 'MyApp::', '+' => '' },
29             #pod };
30             #pod
31             #pod my @to_load = rewrite_dt_prefix( qw(Plugin Mixin Addon +Corporate::Thinger));
32             #pod
33             #pod # now you have:
34             #pod qw(MyApp::Plugin MyApp::Mixin MyApp::Addon Corporate::Thinger)
35             #pod
36             #pod =method rewrite
37             #pod
38             #pod String::RewritePrefix->rewrite(\%prefix, @strings);
39             #pod
40             #pod This rewrites all the given strings using the rules in C<%prefix>. Its keys
41             #pod are known prefixes for which its values will be substituted. This is performed
42             #pod in longest-first order, and only one prefix will be rewritten.
43             #pod
44             #pod If the prefix value is a coderef, it will be executed with the remaining string
45             #pod as its only argument. The return value will be used as the prefix.
46             #pod
47             #pod =cut
48              
49             sub rewrite {
50 18     18 1 764 my ($self, $arg, @rest) = @_;
51 18         60 return $self->_new_rewriter(rewrite => { prefixes => $arg })->(@rest);
52             }
53              
54             sub _new_rewriter {
55 23     23   2145 my ($self, $name, $arg) = @_;
56 23   50     55 my $rewrites = $arg->{prefixes} || {};
57              
58 23         30 my @rewrites;
59 23         83 for my $prefix (sort { length $b <=> length $a } keys %$rewrites) {
  64         112  
60 71         133 push @rewrites, ($prefix, $rewrites->{$prefix});
61             }
62              
63             return sub {
64 38     38   5159 my @result;
65              
66 38 50       73 Carp::cluck("string rewriter invoked in void context")
67             unless defined wantarray;
68              
69 38 100       69 if ( ! wantarray) {
70 29 50       62 Carp::croak("attempt to rewrite multiple strings outside of list context")
71             if @_ > 1;
72              
73 29 50       45 Carp::cluck("rewrite invoked without args")
74             if @_ == 0;
75             }
76              
77 38         62 STRING: for my $str (@_) {
78 71         121 for (my $i = 0; $i < @rewrites; $i += 2) {
79 159 100       310 if (index($str, $rewrites[$i]) == 0) {
80 66 100       113 if (ref $rewrites[$i+1]) {
81 10         19 my $rest = substr $str, length($rewrites[$i]);
82 10         20 my $str = $rewrites[ $i+1 ]->($rest);
83 10 100       62 push @result, (defined $str ? $str : '') . $rest;
84             } else {
85 56         128 push @result, $rewrites[$i+1] . substr $str, length($rewrites[$i]);
86             }
87 66         132 next STRING;
88             }
89             }
90              
91 5         9 push @result, $str;
92             }
93              
94 38 100       240 return wantarray ? @result : $result[0];
95 23         113 };
96             }
97              
98             1;
99              
100             __END__