File Coverage

blib/lib/Common/CodingTools.pm
Criterion Covered Total %
statement 71 72 98.6
branch 20 30 66.6
condition 6 17 35.2
subroutine 14 14 100.0
pod 9 9 100.0
total 120 142 84.5


line stmt bran cond sub pod time code
1             package Common::CodingTools;
2              
3 3     3   276130 use strict;
  3         4  
  3         94  
4 3     3   11 no strict 'subs'; # Needed for constants
  3         5  
  3         172  
5              
6             =encoding utf8
7              
8             =head1 NAME
9              
10             Common::CodingTools - Common constants and functions for programmers
11              
12             =head1 SYNOPSIS
13              
14             ## Global Tag
15             # :all
16              
17             ## Constants Tags
18             # :contants
19             # :boolean
20             # :toggle
21             # :activity
22             # :health
23             # :expiration
24             # :cleanliness
25             # :emotion
26             # :success
27             # :want
28             # :pi
29              
30             ## Functions Tags
31             # :functions
32             # :file
33             # :trim
34             # :schwartz
35             # :weird
36             # :string
37              
38             use Common::CodingTools qw(:all);
39              
40             =head1 DESCRIPTION
41              
42             Something to use for just about any Perl project, as typical as "use strict". It pre-defines some constants for easy boolean checks and has available functions Perl should have included by default.
43              
44             =head2 IMPORT CONSTANTS
45              
46             In addition to the defaults, you can use constants that better reflect the purpose of the code
47              
48             Positive names (equals 1)
49              
50             =over 4
51              
52             =item TRUE
53              
54             =item SUCCESS
55              
56             =item SUCCESSFUL
57              
58             =item SUCCEEDED
59              
60             =item HAPPY
61              
62             =item CLEAN
63              
64             =item EXPIRED
65              
66             =item HEALTHY
67              
68             =item ON
69              
70             =item ACTIVE
71              
72             =item WANTED
73              
74             =back
75              
76             Negative names (equals 0)
77              
78             =over 4
79              
80             =item FALSE
81              
82             =item FAILURE
83              
84             =item FAILED
85              
86             =item FAIL
87              
88             =item SAD
89              
90             =item ANGRY
91              
92             =item DIRTY
93              
94             =item NOTEXPIRED
95              
96             =item UNHEALTHY
97              
98             =item OFF
99              
100             =item INACTIVE
101              
102             =item UNWANTED
103              
104             =back
105              
106             =head2 IMPORT FUNCTIONS
107              
108             Helpful functions you can import into your code
109              
110             =over 4
111              
112             =item slurp_file
113              
114             =item ltrim
115              
116             =item rtrim
117              
118             =item trim
119              
120             =item tfirst
121              
122             =item uc_lc
123              
124             =item center
125              
126             =item schwartzian_sort
127              
128             =back
129              
130             =head2 IMPORT TAGS
131              
132             All parameters are prefixed with :
133              
134             =head3 CONSTANTS
135              
136             =over 4
137              
138             =item :all
139              
140             Imports all functions, constants and tags
141              
142             =item :functions
143              
144             Imports all functions
145              
146             =item :constants
147              
148             Imports all contants
149              
150             =item :boolean
151              
152             Inports the constants TRUE and FALSE
153              
154             =item :toggle
155              
156             Imports the constants ON and OFF
157              
158             =item :activity
159              
160             Imports the constants ACTIVE and INACTIVE
161              
162             =item :health
163              
164             Imports the constants HEALTHY and UNHEALTHY
165              
166             =item :expiration
167              
168             Imports the constants EXPIRED and NOTEXPIRED
169              
170             =item :cleanliness
171              
172             Imports the constants CLEAN and DIRTY
173              
174             =item :emotion
175              
176             Imports the constants HAPPY, UNHAPPY, SAD and ANGRY
177              
178             =item :success
179              
180             Imports the constants SUCCESS, SUCCESSFUL, SUCCEEDED, FAILURE, FAILED and FAIL
181              
182             =item :want
183              
184             Imports the constants WANTED and UNWANTED
185              
186             =item :pi
187              
188             Imports the constant PI (the mathematical value of pi)
189              
190             =back
191              
192             =head3 FUNCTIONS
193              
194             =over 4
195              
196             =item :file
197              
198             Imports the function "slurp_file"
199              
200             =item :trim
201              
202             Imports the functions "ltrim", "rtrim" and "trim"
203              
204             =item :schwarts
205              
206             Import the function "schwartzian_sort"
207              
208             =item :weird
209              
210             Import the function "uc_lc"
211              
212             =item :string
213              
214             Import the functions/tags ":trim", ":weird-case" and "center"
215              
216             =back
217              
218             =cut
219              
220 3     3   14 use List::Util qw(max);
  3         6  
  3         404  
221             use constant {
222 3         627 FALSE => 0,
223             TRUE => 1,
224             ON => 1,
225             OFF => 0,
226             ACTIVE => 1,
227             INACTIVE => 0,
228             SUCCESS => 1,
229             SUCCEEDED => 1,
230             SUCCESSFUL => 1,
231             FAILURE => 0,
232             FAILED => 0,
233             FAIL => 0,
234             WANTED => 1,
235             UNWANTED => 0,
236             HAPPY => 1,
237             UNHAPPY => 0,
238             SAD => 0,
239             ANGRY => 0,
240             CLEAN => 1,
241             DIRTY => 0,
242             EXPIRED => 1,
243             NOTEXPIRED => 0,
244             HEALTHY => 1,
245             UNHEALTHY => 0,
246             PI => (4 * atan2(1, 1)),
247 3     3   13 };
  3         7  
248              
249             BEGIN {
250 3     3   4268 our $VERSION = 2.06;
251             }
252              
253             require Exporter;
254              
255             our @ISA = qw(Exporter);
256              
257             our @EXPORT = qw();
258             our @EXPORT_OK = qw(
259             TRUE FALSE
260             SUCCESS SUCCESSFUL SUCCEEDED FAILURE FAILED FAIL
261             HAPPY UNHAPPY SAD ANGRY
262             CLEAN DIRTY
263             EXPIRED NOTEXPIRED
264             HEALTHY UNHEALTHY
265             ON OFF
266             ACTIVE INACTIVE
267             WANTED UNWANTED
268              
269             PI
270              
271             slurp_file
272             ltrim
273             rtrim
274             trim
275             tfirst
276             uc_lc
277             leet_speak
278             center
279             schwartzian_sort
280             );
281             our %EXPORT_TAGS = (
282             'boolean' => [qw(TRUE FALSE)],
283             'toggle' => [qw(ON OFF)],
284             'want' => [qw(WANTED UNWANTED)],
285             'activity' => [qw(ACTIVE INACTIVE)],
286             'health' => [qw(HEALTHY UNHEALTHY)],
287             'expiration' => [qw(EXPIRED NOTEXPIRED)],
288             'cleanliness' => [qw(CLEAN DIRTY)],
289             'emotion' => [qw(HAPPY UNHAPPY SAD ANGRY)],
290             'success' => [qw(SUCCESS SUCCESSFUL SUCCEEDED FAILURE FAILED FAIL)],
291             'pi' => [qw(PI)],
292             'file' => [qw(slurp_file)],
293             'trim' => [qw(ltrim rtrim trim)],
294             'schwartz' => [qw(schwartzian_sort)],
295             'weird' => [qw(uc_lc leet_speak)],
296             'weird-case' => [qw(uc_lc leet_speak)],
297             'string' => [qw(ltrim rtrim trim uc_lc leet_speak center tfirst)],
298             'constants' => [
299             qw(
300             ON OFF
301             SUCCESS SUCCESSFUL SUCCEEDED FAILURE FAILED FAIL
302             ACTIVE INACTIVE
303             HEALTHY UNHEALTHY EXPIRED NOTEXPIRED
304             CLEAN DIRTY
305             HAPPY UNHAPPY SAD ANGRY
306             WANTED UNWANTED
307             PI
308             TRUE FALSE
309             )
310             ],
311             'functions' => [
312             qw(
313             slurp_file
314             ltrim rtrim trim uc_lc leet_speak
315             schwartzian_sort
316             center
317             tfirst
318             )
319             ],
320             'all' => [
321             qw(
322             ON OFF
323             SUCCESS SUCCESSFUL SUCCEEDED FAILURE FAILED FAIL
324             ACTIVE INACTIVE
325             HEALTHY UNHEALTHY EXPIRED NOTEXPIRED
326             CLEAN DIRTY
327             HAPPY UNHAPPY SAD ANGRY
328             WANTED UNWANTED
329             PI
330             TRUE FALSE
331             slurp_file
332             ltrim rtrim trim uc_lc leet_speak
333             schwartzian_sort
334             center
335             tfirst
336             )
337             ],
338             );
339              
340             =head1 FUNCTIONS
341              
342             X
343             X
344             X
345             X
346             X
347             X
348             X
349             X
350              
351             =head2 slurp_file
352              
353             Reads in a text file and returns the contents of that file as a single string. It returns undef if the file is not found.
354              
355             my $string = slurp_file('/file/name');
356              
357             =cut
358              
359             sub slurp_file {
360 2     2 1 347514 my $file = shift;
361              
362             # Read in a text file without using open
363 2 50       68 if (-e $file) {
364             return (
365 2         6 do { local (@ARGV, $/) = $file; <> }
  2         23  
  2         249  
366             );
367             }
368 0         0 return (undef);
369             } ## end sub slurp_file
370              
371             =head2 ltrim
372              
373             Removes any spaces at the beginning of a string (the left side).
374              
375             my $result = ltrim($string);
376              
377             =cut
378              
379             sub ltrim {
380 4     4 1 579 my $string = shift;
381 4 50 33     29 if (defined($string) && $string ne '') {
382 4         26 $string =~ s/^\s+//g;
383             }
384 4         26 return ($string);
385             } ## end sub ltrim
386              
387             =head2 rtrim
388              
389             Removes any spaces at the end of a string (the right side).
390              
391             my $result = rtrim($string);
392              
393             =cut
394              
395             sub rtrim {
396 4     4 1 11 my $string = shift;
397 4 50 33     20 if (defined($string) && $string ne '') {
398 4         24 $string =~ s/\s+$//g;
399             }
400 4         18 return ($string);
401             } ## end sub rtrim
402              
403             =head2 trim
404              
405             Removes any spaces at the beginning and the end of a string.
406              
407             my $result = trim($string);
408              
409             =cut
410              
411             sub trim {
412 4     4 1 8 my $string = shift;
413 4 50 33     24 if (defined($string) && $string ne '') {
414 4         28 $string =~ s/^\s+|\s+$//g;
415             }
416 4         22 return ($string);
417             } ## end sub trim
418              
419             =head2 center
420              
421             Centers a string, padding with leading spaces, in the middle of a given width.
422              
423             my $result = center($string, 80); # Centers text for an 80 column display
424              
425             =cut
426              
427             sub center {
428 4   50 4 1 15 my $string = shift || '';
429 4         19 my $size = max(shift, length($string));
430              
431 4         9 my $csize = int($size - length($string));
432 4         12 my $tab = int($csize / 2);
433 4         9 my $format = '%-' . $size . 's';
434 4 50       16 $string = ' ' x $tab . $string if ($tab > 0);
435 4         14 $string = sprintf($format, $string);
436 4         19 return ($string);
437             } ## end sub center
438              
439             =head2 uc_lc
440              
441             This changes text to annoying "leet-speak".
442              
443             my $result = uc_lc($string, 1); # Second parameter determs whether to start with upper or lower-case. You can leave out that parameter for random pick.
444              
445             =cut
446              
447             sub uc_lc {
448 16     16 1 32 my $string = shift;
449 16 50       38 my $start = (scalar(@_)) ? shift : int(rand(2));
450              
451 16 50 33     72 if (defined($string) && $string ne '') {
452 16         23 my $l = length($string);
453              
454 16         37 for (my $count = 0; $count < $l; $count++) {
455 268         424 my $c = substr($string, $count, 1);
456 268 100       608 if ($c =~ /\w/) {
457 232 100       363 if ($start) {
458 116         198 substr($string, $count, 1) = uc($c);
459 116         230 $start = 0;
460             } else {
461 116         180 substr($string, $count, 1) = lc($c);
462 116         233 $start = 1;
463             }
464             } ## end if ($c =~ /\w/)
465             } ## end for (my $count = 0; $count...)
466             } ## end if (defined($string) &&...)
467 16         91 return ($string);
468             } ## end sub uc_lc
469              
470             =head2 leet_speak (same as uc_lc)
471              
472             This changes text to annoying "leet-speak".
473              
474             my $result = leet_speak($string, 1); # Second parameter determs whether to start with upper or lower-case. You can leave out that parameter for random pick.
475              
476             =cut
477              
478             sub leet_speak {
479 8     8 1 20 return(uc_lc(@_));
480             }
481              
482             =head2 schwartzian_sort
483              
484             Sorts a rather large list with the very fast Swartzian sort. It returns either an array or a reference to an array, depending how it was called.
485              
486             my @sorted = schwartzian_sort(@unsorted); # Can be slower with large arrays due to stack overhead.
487              
488             or
489              
490             my $sorted = schwartzian_sort(\@unsorted); # Pass a reference and returns a reference (faster for large arrays)
491              
492             =cut
493              
494             sub schwartzian_sort {
495 8     8 1 2083 my $wa = wantarray;
496 8 100       26 if (scalar(@_) == 1) {
497 4         8 @_ = @{$_[0]};
  4         16  
498             }
499 36         68 my @sorted = map { $_->[1] }
500 48         89 sort { $a->[0] cmp $b->[0] }
501 8         21 map { [lc($_), $_] } @_;
  36         102  
502 8 100       46 return(($wa) ? @sorted : \@sorted);
503             }
504              
505             =head2 tfirst
506              
507             Change text into "title ready" text with each word capitalized.
508              
509             my $title = tfirst($string);
510              
511             For example:
512              
513             my $before = 'this is a string I want to turn into a title-ready string';
514              
515             my $title = tfirst($before);
516              
517             # $title is now 'This Is a String I Want To Turn Into a Title-ready String'
518              
519             =cut
520              
521             sub tfirst {
522             #
523             # This function, tfirst, is based upon TitleCase code by the following authors:
524             #
525             # 10 May 2008
526             # Original version by John Gruber:
527             # http://daringfireball.net/2008/05/title_case
528             #
529             # 28 July 2008
530             # Re-written and much improved by Aristotle Pagaltzis:
531             # http://plasmasturm.org/code/titlecase/
532             #
533             # License: http://www.opensource.org/licenses/mit-license.php
534             #
535 4     4 1 10 my $string = shift;
536 4 50 33     26 if (defined($string) && $string ne '') {
537              
538             # Define what little words are first.
539 4         23 my @little_guys = qw( (?
540              
541             # Change this into a regexp portion.
542 4         19 my $little_regexp = join '|', @little_guys;
543              
544 4         20 my $psa = qr/ (?: ['’] [[:lower:]]* )? /x;
545              
546 4         1208 $string =~ s{
547             \b (_*) (?:
548             ( [-_[:alpha:]]+ [@.:/] [-_[:alpha:]@.:/]+ $psa ) | # Internet address?
549             ( (?i: $little_regexp ) $psa ) | # or little word (case-insensitive)?
550             ( [[:alpha:]] [[:lower:]'’()\[\]{}]* $psa ) | # or word without internal capitals?
551             ( [[:alpha:]] [[:alpha:]'’()\[\]{}]* $psa ) # or other type of word
552             ) (_*) \b
553             }{
554 32 50       253 $1 . (
    100          
    50          
555             defined $2 ? $2 # Please keep Internet specific addresses
556             : defined $3 ? "\L$3" # This is a lowercase little word
557             : defined $4 ? "\u\L$4" # Now capitalize the word without internal capitals
558             : $5 # Please preserve other type words
559             ) . $6
560             }exgo;
561              
562             # Further processing for little words and other unique title rules
563 4         407 $string =~ s{
564             ( \A [[:punct:]]* # Title beginning
565             | [:.;?!][ ]+ # or perhaps a subsentence?
566             | [ ]['"“‘(\[][ ]* ) # or perhaps a subphrase?
567             ( $little_regexp ) \b # is it followed by little word?
568             }{$1\u\L$2}xigo;
569              
570 4         280 $string =~ s{
571             \b ( $little_regexp ) # The word is little
572             (?= [[:punct:]]* \Z # are we at the end of the title?
573             | ['"’”)\]] [ ] ) # or a subphrase?
574             }{\u\L$1}xigo;
575             } ## end if (defined($string) &&...)
576 4         41 return ($string);
577             } ## end sub tfirst
578              
579             1;
580              
581             =head1 AUTHOR
582              
583             Richard Kelsch
584              
585             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
586              
587             =head1 VERSION
588              
589             Version 2.06 (April 15, 2026)
590              
591             =head1 BUGS
592              
593             Please report any bugs or feature requests to bug-commoncodingtools at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CommonCodingTools. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
594              
595             =head1 SUPPORT
596              
597             You can find documentation for this module with the perldoc command.
598              
599             perldoc Common::CodingTools
600              
601             You can also look for information at:
602              
603             =over 4
604              
605             =item RT: CPAN's request tracker (report bugs here)
606              
607             L
608              
609             =item AnnoCPAN: Annotated CPAN documentation
610              
611             L
612              
613             =item CPAN Ratings
614              
615             L
616              
617             Not exactly a reliable and fair means of rating modules. Modules are updated and improved over time, and what may have been a poor or mediocre review at version 0.04, may not remotely apply to current or later versions. It applies ratings in an arbitrary manner with no ability for the author to add their own rebuttals or comments to the review, especially should the review be malicious or inapplicable.
618              
619             More importantly, issues brought up in a mediocre review may have been addressed and improved in later versions, or completely changed to allieviate that issue.
620              
621             So, check the reviews AND the version number when that review was written.
622              
623             =item Search CPAN
624              
625             L
626              
627             =item GitHub
628              
629             L
630              
631             =back
632              
633             =head1 COPYRIGHT
634              
635             Copyright (C) 2016 Richard Kelsch,
636             All Rights Reserved
637              
638             The B subroutine is Copyright (C) 2008 John Gruber as "TitleCase"
639              
640             =head1 LICENSES
641              
642             =over 4
643              
644             =item B
645              
646             =back
647              
648             =over 4
649              
650             This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:
651              
652             L
653              
654             =back
655              
656             =over 4
657              
658             =item B
659              
660             =back
661              
662             =over 4
663              
664             The B routine only, is under the MIT license as "TitleCase".
665              
666             L
667              
668             =back
669              
670             =cut
671              
672             __END__