File Coverage

blib/lib/Text/Naming/Convention.pm
Criterion Covered Total %
statement 87 92 94.5
branch 40 48 83.3
condition 26 27 96.3
subroutine 9 9 100.0
pod 4 4 100.0
total 166 180 92.2


line stmt bran cond sub pod time code
1             package Text::Naming::Convention;
2              
3 2     2   26632 use warnings;
  2         3  
  2         51  
4 2     2   6 use strict;
  2         2  
  2         28  
5 2     2   5 use Carp;
  2         4  
  2         115  
6              
7 2     2   7 use base qw/Exporter/;
  2         1  
  2         1685  
8             our @EXPORT_OK = qw/naming renaming default_convention default_keep_uppers/;
9              
10             our $VERSION = '0.07';
11              
12             my @_valid_conventions = ( '_', '-', 'UpperCamelCase', 'lowerCamelCase' );
13             my $_default_convention = '_';
14              
15             # keep the upper case for word like 'RFC', but not 'bAr', that only take
16             # effect for CamelCase conventions, and not the first word if it's
17             # lowerCamelCase.
18             my $_default_keep_uppers = 1;
19              
20             =head1 NAME
21              
22             Text::Naming::Convention - Naming or Renaming( for identifiers, mostly )
23              
24              
25             =head1 VERSION
26              
27             This document describes Text::Naming::Convention version 0.06
28              
29              
30             =head1 SYNOPSIS
31              
32             use Text::Naming::Convention qw/naming renaming/;
33             my $name = naming( 'foo', 'bar', 'baz' ) # got foo_bar_baz
34             $name = naming( 'foo', 'bar', 'baz',
35             { convention => 'UpperCamelCase'} ); # got FooBarBaz
36             my $new_name = renaming( 'FooBarBaz' ); # got foo_bar_baz
37             $new_name = renaming( 'FooBarBaz',
38             { convention => 'lowerCamelCase' } ); # got fooBarBaz
39              
40              
41             =head1 DESCRIPTION
42              
43             This's a simple module for naming and renaming, mostly for identifiers or something like that.
44              
45             I'm tired of writing renaming sub, so I chose to create this module, wish it can help you too :)
46              
47             =head2 default_convention
48              
49             get or set default convention, default is '_'.
50             valid values are ( '_', '-', 'UpperCamelCase', 'lowerCamelCase' ).
51             return the default convention.
52              
53             =cut
54              
55             sub default_convention {
56 3     3 1 11 my $convention = shift;
57 3 100       9 return $_default_convention unless $convention;
58              
59 2 50       4 if ( grep { $_ eq $convention } @_valid_conventions ) {
  8         16  
60 2         4 $_default_convention = $convention;
61             }
62             else {
63 0         0 carp "invalid convention: $convention";
64             }
65 2         8 return $_default_convention;
66             }
67              
68             =head2 default_keep_uppers
69              
70             keep words of uppers or not, here uppers means all uppers like 'BAR', not 'bAr'.
71             default value is true
72              
73             =cut
74              
75             sub default_keep_uppers {
76 2 100   2 1 340 if (@_) {
77 1         2 $_default_keep_uppers = shift;
78             }
79 2         11 return $_default_keep_uppers;
80              
81             }
82              
83             =head2 naming
84              
85             given a list of words, return the named string
86             the last arg can be hashref that supplies option like:
87             { convention => 'UpperCamelCase' }
88              
89             =cut
90              
91             sub naming {
92 14     14 1 2422 my @words = @_;
93 14         22 my $convention = $_default_convention;
94 14         14 my $keep_uppers = $_default_keep_uppers;
95              
96 14 100       38 if ( ref $words[-1] eq 'HASH' ) {
97 10         12 my $option = pop @words;
98              
99             # the last element is option
100 10 50       19 if ( _is_valid_convention( $option->{convention} ) ) {
101 10         16 $convention = $option->{convention};
102             }
103             else {
104 0         0 carp "invlid convention: $option->{convention}";
105             }
106              
107 10 50       23 if ( exists $option->{keep_uppers} ) {
108 0         0 $keep_uppers = $option->{keep_uppers};
109             }
110             }
111              
112 14         19 for my $word (@words) {
113 50 100 100     251 next if $keep_uppers && $word =~ /^[A-Z]+$/ && $convention =~ /Camel/;
      100        
114 46         69 $word = lc $word;
115             }
116              
117 14 100       44 if ( $convention eq '_' ) {
    100          
    100          
    50          
118 4         32 return join '_', @words;
119             }
120             elsif ( $convention eq '-' ) {
121 4         35 return join '-', @words;
122             }
123             elsif ( $convention eq 'UpperCamelCase' ) {
124 3         5 return join '', map { ucfirst } @words;
  11         42  
125             }
126             elsif ( $convention eq 'lowerCamelCase' ) {
127 3         6 my $first = shift @words;
128 3         5 $first = lc $first;
129 3         4 return $first . join '', map { ucfirst } @words;
  8         49  
130             }
131             else {
132 0         0 carp "invalid $convention: $convention";
133             }
134             }
135              
136             sub _is_valid_convention {
137 43     43   56 my $convention = shift;
138 43 50       80 return unless $convention;
139 43         61 return grep { $_ eq $convention } @_valid_conventions;
  172         297  
140             }
141              
142             =head2 renaming
143              
144             given a name, renaming it with another convention.
145             the last arg can be hashref that supplies option like:
146             { convention => 'UpperCamelCase' }
147              
148             return the renamed one.
149              
150             if the convention is the same as the name, just return the name.
151              
152             if without arguments and $_ is defined and it's not a reference, renaming $_
153              
154              
155             =cut
156              
157             sub renaming {
158              
159 42     42 1 4078 my ($name, $option);
160 42 100 100     93 if ( scalar @_ ) {
    100          
161 38         43 $name = shift;
162 38         37 $option = shift;
163             }
164             elsif ( defined $_ && ! ref $_ ) {
165 2         4 $name = $_;
166             }
167             else {
168             return
169 2         12 }
170              
171 40         51 my $convention = $_default_convention;
172              
173 40 100 66     174 if ( $option && ref $option eq 'HASH' ) {
174              
175             # the last element is option
176 33 50       59 if ( _is_valid_convention( $option->{convention} ) ) {
177 33         53 $convention = $option->{convention};
178             }
179             else {
180 0         0 carp "invlid convention: $option->{convention}";
181             }
182              
183             }
184              
185 40 100 100     187 if ( $name =~ /(_)/ || $name =~ /(-)/ ) {
186 8         16 my $from = $1;
187 8 50       16 return $name if $convention eq $from;
188              
189 8 100 100     30 if ( ( $convention eq '_' || $convention eq '-' ) )
190             {
191 4         72 $name =~ s/$from/$convention/g;
192 4         26 return $name;
193             }
194             else {
195 4         47 $name =~ s/$from(.)/uc $1/ge;
  8         25  
196 4 50       10 return ucfirst $name if $convention eq 'UpperCamelCase';
197 4         29 return $name;
198             }
199             }
200             else {
201 32 100 100     106 if ( $convention eq '_' || $convention eq '-' ) {
202             # massage the first word, FOOBar => fooBar
203 19         54 $name =~ s/^([A-Z])([^A-Z])/lc( $1 ) . $2/e;
  8         36  
204 19         38 $name =~ s/^([A-Z]+)(?![a-z])/lc $1/e;
  2         8  
205              
206             # massage the last word, FooBAR => FooBar
207 19         43 $name =~ s/(?<=[A-Z])([A-Z]+(\d+)?)$/lc( $1 )/e;
  2         6  
208              
209             # e.g. fooBARBaz => foo_bar_baz
210             # first step: fooBARBaz => fooBarBaz
211             # second step: fooBarBaz => foo_bar_baz
212 19         34 $name =~ s/([A-Z]+)([A-Z])/(ucfirst lc $1 ) . $2/ge;
  1         5  
213 19         54 $name =~ s/([^A-Z])([A-Z])/$1 . $convention . lc $2/ge;
  17         75  
214             # tr all the weirdly left [A-Z]
215 19         34 $name =~ tr/A-Z/a-z/;
216             }
217             else {
218 13         14 my $from = 'UpperCamelCase';
219 13 100       39 $from = 'lowerCamelCase' if $name =~ /^[^A-Z]/;
220 13 100 100     66 if ( $convention eq 'UpperCamelCase' && $convention ne $from ) {
    100 100        
221 6         41 return ucfirst $name;
222             }
223             elsif ( $convention eq 'lowerCamelCase' && $convention ne $from ) {
224 3         11 $name =~ s/^([A-Z])([^A-Z])/lc( $1 ) . $2/e;
  2         10  
225 3         9 $name =~ s/^([A-Z]+)(?![a-z])/lc $1/e;
  1         5  
226 3         20 return $name;
227             }
228             }
229             }
230 23         126 return $name;
231             }
232              
233             1;
234              
235             __END__