Re: Reducing repetitive code
by duff (Parson) on Jan 06, 2004 at 16:30 UTC
|
First off, you have an error in February's conditional. Secondly, you could take advantage of perl's if-it-looks-like-a-number-it-is and do this:
my @months = qw(January February March April May June July August Sept
+ember October November December);
print $months[$realmonth-1];
Thirdly, since you're dealing with dates, you should probably be using one of the DateTime modules or at least POSIX::strftime.
Update: Fixed the off-by-one error in my array index.
| [reply] [d/l] |
Re: Reducing repetitive code
by dragonchild (Archbishop) on Jan 06, 2004 at 16:34 UTC
|
Use an array or a hash. Personally, I'd use an hash here, for the ease of error-handling and the fact that your indices don't begin at 0.
my %month_names = do {
my $i = 1;
map { sprintf("%02d", $i++) => $_ } qw(
January Feburary March
April May June
July August September
October November December
)
};
sub get_monthname
{
my ($month_num) = @_;
$month_num = sprintf("%02d", $month_num);
return $month_names{$month_num};
}
Now, the nice thing is that if you pass in something like '13' or 'aaa', it will return undef. (It will also throw a warning with the 'aaa' one, but you can bypass that with a well-placed no warnings 'number'.) And, it will do the right thing with '1', '01', and '0001'.
------
We are the carpenters and bricklayers of the Information Age.
Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.
| [reply] [d/l] [select] |
|
|
A hash was my first thought, too, but after reading duff's solution, I think an array is better. The lookup time will be faster, and the off-by-one problem is trivial to get around. Perl will numify '01' and '1' to the same thing, so there's no problem there. Also, it's easier to build the array than it is to map the months into a hash.
---- I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
-- Schemer
: () { :|:& };:
Note: All code is untested, unless otherwise stated
| [reply] [d/l] |
|
|
An array is better ... except that
- all non-numbers will return 'January'.
- 1234567890 will blow your memory out of the water with an array, but will behave with a hash.
- -2 will behave non-deterministically. (If it's the first run, will return November. But, if you tried 13, it will then return December.)
- -40 will die a horrible death.
Now, my complaints originate from having to be defensive. If you can assume that my complaints won't occur, then, by all mean, use an array for speed and intuitiveness.
------
We are the carpenters and bricklayers of the Information Age.
Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.
| [reply] |
|
|
|
|
|
|
|
|
if ( $realmonth >0 and $realmonth <=12 ) {
print $monthname[$realmonth-1];
} else {
warn "Invalid value for realmonth: $realmonth\n";
}
| [reply] [d/l] |
Re: Reducing repetitive code
by broquaint (Abbot) on Jan 06, 2004 at 16:36 UTC
|
Code like that is usually prime for a hash e.g
# a zip() function would be handy here (see. Language::Functional)
my $i = 1;
my %months = map { $i++ => $_ }
qw(January February March April May June
July August September October November December);
printf "%2s: %s\n", $_, $months{ sprintf '%d', $_ }
for qw( 09 4 06 11 );
__output__
09: September
4: April
06: June
11: November
| [reply] [d/l] |
Re: Reducing repetitive code
by davido (Cardinal) on Jan 06, 2004 at 17:23 UTC
|
Here's a concise version that uses a hash, a hash slice, and substitution.
my %months;
@months{1..12} = qw/January February March April May
June July August September October
November December/;
my $numeric_month = "01"; # Test case.
my $string_month;
$numeric_month =~ s/0(\d)/$1/;
if ( exists( $months{$numeric_month} ) ) {
$string_month = $months{$numeric_month}
} else {
die "Invalid month format.\n";
}
| [reply] [d/l] |
Re: Reducing repetitive code
by Paulster2 (Priest) on Jan 06, 2004 at 21:37 UTC
|
I didn't see it mentioned above, so will mention the mod Date::Manip that will save you a ton of repetitive motions with anything to do with dates. You can use just about any type of manipulation that you would like. With it you can pretty much eliminate setting up arrays with month names (October, November, ...), or names of the days (Tuesday, Wednesday, Thursday, ...) or anything having to do with dates. Read the perldoc on it and you will find it quite comprehensive. I find the perldoc so comprehensive, infact, I use it to get the formating I can never seem to remember with using date on UNIX systems. Check it out, I believe that you will like it.
UPDATE: Fixed the CPAN link.
| [reply] [d/l] |
Re: Reducing repetitive code
by artist (Parson) on Jan 06, 2004 at 18:34 UTC
|
Perhaps the following will help you for the bigger picture you are trying to solve:
use DateTime;
$dt = DateTime->now;
$month_name = $dt->month_name;
It prints full names of month as you desired.
| [reply] [d/l] |
Re: Reducing repetitive code
by cLive ;-) (Prior) on Jan 06, 2004 at 19:58 UTC
|
my @months = qw(January February March April May
June July August September October
November December);
print $months[$realmonth-1];
.02
cLive ;-) | [reply] [d/l] |