views:

1441

answers:

9

If I import a library to use a method, would it be worth it? Does importing take up a lot of memory?

+9  A: 

Importing such a module is not likely to cost that much memory that you should refrain from it, though in this case probably a simple hash would be just as good. Something like

my %number_for = (
    jan => 1,
    feb => 2,
#etc...
);
#...
do_something_with($number_for{$month})
Leon Timmermans
+17  A: 

borrowed from here

%mon2num = qw(
    jan 1  feb 2  mar 3  apr 4  may 5  jun 6
    jul 7  aug 8  sep 9  oct 10 nov 11 dec 12
);

and to retrieve

$mon2num{"jan"}
Oskar
+2  A: 
my %month_num = do { my $i = 1; map {; $_ => $i++ } (
    qw( jan feb mar apr may jun jul aug sep oct nov dec )
) };

Or maybe:

my %month_num;
$month_num{ $_ } = 1 + keys %month_num for (
    qw( jan feb mar apr may jun jul aug sep oct nov dec )
);

Or using a zip function:

my %month_num = do {
    my @month = qw( jan feb mar apr may jun jul aug sep oct nov dec );
    zip2( 1 .. 1+$#month, @month );
};
Aristotle Pagaltzis
This is much more complicated than it needs to be.
Brad Gilbert
Getting too clever, and as Brad said, making it more complicated than it needs to be. It's good to show that TMTOWTDI, but those ways are unnecessarily convoluted, IMO.
David Precious
Nice to have the simple solution, nicer to have well written generalizable solutions. Good stuff, thanks.
jaredor
The goal was not to have to write down redundant information – the month number is given by the position of the month name in the month name list anyway. I agree that none of the solutions turned out as elegant and simple as I had hoped for.
Aristotle Pagaltzis
!? I came back to this solution to bookmark it. These solutions scale while avoiding data redundancy and ergo, are elegant. The simple solution has been given and has been identified as very good for this specific case. These solutions (#2 is my fave, though I love to use map) are "the next step".
jaredor
Yes. It’s just easy to imagine that they could be even simpler to write somehow, considering how trivial the goal is. Measured against it, all my solutions feel disproportionately complicated, even though on an absolute scale they are pretty trivial.
Aristotle Pagaltzis
Forgive me for seeming obsessive, but this afternoon I just read this line from p141 in *Higher Order Perl* by Mark Jason Dominus: my %fieldnum = map { uc $field[$_] => $_ } (0..$#field);and thereby I think you can add a little more simplicity to your Ex #1 (though you'd have to define @month).
jaredor
+9  A: 

Here is yet another way to do it:

my %month; @month{qw/jan feb mar apr may jun
                     jul aug sep oct nov dec/} = (1 .. 12);
Robert Krimen
A: 

It depends on how much date manipulation you're intending to do. At first you're probably better off with hand-rolling it, e.g.

my @months = qw(Jan Feb Mar Apr May Jun
                Jul Aug Sep Oct Nov Dec);
my %monthnum = map { $_ => $months[ $_ - 1 ] } 1..12;

(I prefer this approach because it's comparatively obvious what you're doing - you have a list of months, then you map them from 1..12 (the numbers that make sense to a human) to 0..11 (the numbers that make sense to a computer). The performance bottlenecks in your code aren't going to be in this sort of code, they'll be in network, database or disc-accessing code, so concentrate on making your code readable.)

As you start adding to your code, you may find that a lot of this stuff is done already by existing modules, and it might be easier to do some of the simple stuff with e.g. Date::Calc. Or you may find a date/time module more suited to your needs; that's beyond the scope of this question.

Bear in mind also that some modules use autosplit, where only those parts of the module that are needed are loaded. Also, the main performance impact of using a large module isn't necessarily RAM, it's probably more likely to be the time/CPU overhead of loading and compiling it before any of your code has ever run.

Sam Kington
He did say in the question 'ie "jan" to 1', so I suspect he wanted the numbering to start from 1 rather than 0 :)
David Precious
A: 

Definitely a hash, as suggested by others.

Guillaume Gervais
+2  A: 

Hmm - there seem to be plenty of overly complicated ways to do this. For something this simple clarity is key:

# create a lookup table of month abbreviations to month numbers
my %month_abbr_to_number_lkup = (
    jan => 1,
    feb => 2,
    mar => 3,
    apr => 4,
    may => 5,
    jun => 6,
    jul => 7,
    aug => 8,
    sep => 9,
    oct => 10,
    nov => 11,
    dec => 12,
);

# get the number for a month
my $number = $month_abbr_to_number_lkup{$abbr}
    || die "Could not convert month abbreviation '$abbr' to a number.";
EvdB
+2  A: 

Note also that hash keys are case sensitive; depending on where your abbreviations are coming from you may want to down-case them first to match the hash keys.

%mon_2_num = (jan => 1,
              feb => 2,
              ...);

$month_number = $mon_2_num{lc($month_name_abbrev)};
F5
+1  A: 

Another way to do this using a hash slice:

@month{qw(jan feb mar apr may jun jul aug sep oct nov dec)} = 1..12;
toolkit