http://www.perlmonks.org?node_id=1192403

As some of you may know, I am trying to become a better Perl writer. Part of it is finding where I wrote something that can be done better by someone else and using the better way.

One time I needed to do a numeric comparison of months written as text. So I wrote a module to get the month numbers needed. After I wrote it, I found to my dismay, I had not needed to write it. Date::Calc had a subroutine called Decode_Month that was much better than what I wrote. I am so embarrassed I did not think to look in Date::Calc first before I wrote my silly little module. Date::Calc is far better at date manipulation than anything I could write. So, I dropped the use of my module for Date::Calc. It was a learning experience I took forward to the rest of my code.

Another part of becoming better is rewriting and renaming the modules I have written. To find names for my modules, I have been crawling CPAN to find what name spaces already exist.

I was looking for a new name for my Util::Number module. I crawled CPAN and found "Number" is a top name space. Then I found Number::Format. I sighed thinking my little Util::Number's days were numbered. Number::Format has a subroutine called round and so did Util::Number. Both do the same thing. Number::Format has a subroutine called format_number that puts commas in numbers and rounds numbers together, just like commify and my pretty_number. I thought commify and pretty_number were not going to be able to match format_number's power.

So, I installed Number::Format and was going to discontinue using my Util::Number. Why? Using Number::Format in code that I need help with, you can install it from CPAN without any trouble. Using Util::Number in code that I need help with, you would have to guess at what it does unless I also put Util::Number in the node with my problem code.

So, I was changing over my code from pretty_number to format_number and making sure it returned what I wanted. Then I got a big surprise. format_number has limitations commify and pretty_number do not have. format_number can not put commas into very big numbers. It outputs an error about the big number and suggests using Math::BigFloat.

format_number

perl -e 'use Number::Format qw(format_number); print format_number(123 +45678987654321)."\n";'

returns...

round() overflow. Try smaller precision or use Math::BigFloat at -e li +ne 1.

commify

perl -e 'use Util::Number qw(commify); print commify(12345678987654321 +)."\n";'

returns...

12,345,678,987,654,321

In the change over from commify and pretty_number to format_number, I got another surprise. format_number does not do ordinal numbers either. I fed it an ordianal number in Happy unbirthday redux! and other birthday stuff, and it returned the following error.

Argument "16725th" isn't numeric in numeric comparison (<=>) at /home/ +me/perl5/lib/perl5/Number/Format.pm line 599.

So, I went back to commify in my code and got...

Happy 16,725th unbirthday, Aleena! You have 32 days until your next bi +rthday on July 10, 2017.

This was all so surprising to me. Here I was ready to use a module readily available on CPAN instead of my own silly little module, but the CPAN module could not do what mine does. I was thinking "But it's is so much better than mine. It's got all those bells and whistles. And it's on CPAN!"

This is not a rant against Number::Format. It is on CPAN and is better written than my little Util::Number. I will use Number::Format in code when I need help. Number::Format also has options I do not currently have, so I will be using it whenever one of those options is needed. Util::Number may become a fallback module when Number::Format will not work for what I am doing currently. Util::Number will not be going to CPAN since I did not write commify or round, I just put them together in pretty_number.

Util::Number

package Util::Number; use strict; use warnings FATAL => qw( all ); use Exporter qw(import); our @EXPORT_OK = qw(commify round pretty_number); # commify was found in the perlfaq5 to put commas in numbers. sub commify { local $_ = shift; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; return $_; } # sprintf written by james2vegas on PerlMonks. sub round { my ($number, $precision) = @_; my $rounded = $number =~ /\./ ? sprintf("%.${precision}f", $number) +: $number; return $rounded; } sub pretty_number { my ($number, $precision) = @_; my $pretty_number = commify(round($number, $precision)); return $pretty_number; } =head1 NAME B<Util::Number> adds commas, rounds, and returns pretty numbers. =head1 SYNOPSIS use Util::Number qw(commify round pretty_number); my $comma_number = commify(2468); # returns 2,468 my $rounded_number = round(0.2468, 3); # returns .247 my $pretty_number = pretty_number(2468.13579, 3); # returns 2,468.136 =head1 DESCRIPTION B<Util::Number> contains three subroutines that make numbers prettier: + C<commify>, C<round>, and C<pretty_number>. =head2 commify B<C<commify>> returns a number with commas between every three digits +in the number. The code was found in L<perlfaq5|http://perldoc.perl.org/perlfaq5.html +#How-can-I-output-my-numbers-with-commas-added?>. =head2 round B<C<round>> rounds a decimal number by a set precision. If you want th +e number returned with three digits after the decimal, the precision +would be set to 3. round($number, $precision); =head2 pretty_number B<C<pretty_number>> puts commify and round together so you can get rou +nded numbers with commas. pretty_number($number, $precision); =head1 AUTHOR Lady Aleena with help =cut 1;

I am trying to make my modules more useful with better names and code. I am also trying to get better by using what is already available. However, sometimes, what is available is a little less than what is wanted. That does not mean I will stop searching.

Afterward...

I cracked opened my now disused month module just to look at it. Then I saw the hash of arrays. What do I do with hashes of arrays of similar data? I randomize it of course. So my Util::MonthNumber is now Random::Month... 8)

Random::Month

package Random::Month; use strict; use warnings FATAL => qw( all ); use Exporter qw(import); our @EXPORT_OK = qw(random_month); use Fancy::Rand qw(fancy_rand); my %months = ( 'English' => [qw(January February March April May June July Aug +ust Spetember October November December)], 'English abbr' => [qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Now De +c)], 'Dutch' => [qw(januari februari maart april mei juni juli aug +ustus september oktober november december)], 'French' => [qw(janvier février mars avril mai juin juillet ao +űt septembre octobre novembre décembre)], 'German' => [qw(Januar Februar März April Mai Juni Juli August + September Oktober November Dezember)], 'Greek' => [qw(Ianuários Fevruários Mártios Aprílios Máios Iú +nios Iúlios Avghustos Septémvrios Októvrios Noémvrios Thekémvrios)], 'Italian' => [qw(gennaio febbraio marzo aprile maggio giugno lu +glio agosto settembre ottobre novembre dicembre)], 'Spanish' => [qw(enero febrero marzo abril mayo junio julio ago +sto septiembre octubre noviembre diciembre)], ); # I wrote this hash for another reason, but Date::Calc killed the need + for the original purpose. sub random_month { my ($user_language, $user_additions) = @_; my $random_month = fancy_rand(\%months, $user_language, { caller => +'random_month', additions => $user_additions ? $user_additions : unde +f }); return $random_month; } =head1 NAME B<Random::Month> selects a random month by language. =head1 SYNOPSIS use Random::Month qw(random_month); my $random_month = random_month(); my $random_English_month = random_month('English'); my $random_Dutch_month = random_month('Dutch'); my $random_French_month = random_month('French'); my $random_German_month = random_month('German'); my $random_Greek_month = random_month('Greek'); my $random_Italian_month = random_month('Italian'); my $random_Spanish_month = rnadom_month('Spanish'); my $random_English_month_abbr = random_month('English abbr'); print random_month('help') # get random_month options =head1 AUTHOR Lady Aleena =cut 1;
No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
Lady Aleena