in reply to Re: Reducing repetitive code
in thread Reducing repetitive code

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

Replies are listed 'Best First'.
Re: Re: Re: Reducing repetitive code
by dragonchild (Archbishop) on Jan 06, 2004 at 19:24 UTC
    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.

      Hmm, all of those could be solved by doing proper input validation. Also, for your second point, just indexing the array doesn't grow it, at least not on my version of perl:

      $ perl -MDevel::Size -e '@a = (0 .. 11); print Devel::Size::total_size +(\@a)' 296 $ perl -MDevel::Size -e '@a = (0 .. 11); $i = $a[56788]; print Devel:: +Size::total_size(\@a)' 296 # Just to make sure perl doesn't optimize away the assignment $ perl -MO=Deparse -MDevel::Size -e '@a = (0 .. 11); $i = $a[56788]; p +rint Devel::Size::total_size(\@a)' -e syntax OK use Devel::Size; @a = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); $i = $a[56788]; print Devel::Size::total_size(\@a); $ perl -v This is perl, v5.8.0 built for MSWin32-x86-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2002, Larry Wall Binary build 806 provided by ActiveState Corp. http://www.ActiveState. +com Built 00:45:44 Mar 31 2003 # snip the rest

      What would grow the array is autovivification, such as if you said $i = $a[57874]{key};.

      ----
      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

        BTW, you'll note that you don't see me arguing the merits of the array solution with dragonchild even though I'm the one who suggested it. Because, of course, I agree with him 100%. Be as paranoid as you think necessary because good programmers are always paranoid about their data :-)

        anyway ... cheers,
        Hmm, all of those could be solved by doing proper input validation.

        That's what I am doing with the hash method.

        just indexing the array doesn't grow it

        You're right ... so long as you're using a newer Perl. Try it on 5.005_3, which is still a very common Perl version in use. (Many companies don't want the risk of recompiling all their modules for 5.6.x or 5.8.x, so they stick with 5.00x_x.)

        ------
        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.

Re: Re: Re: Reducing repetitive code
by graff (Chancellor) on Jan 06, 2004 at 19:44 UTC
    dragonchilds' concerns are quite valid, and easily handled while keeping to a simple array:
    if ( $realmonth >0 and $realmonth <=12 ) { print $monthname[$realmonth-1]; } else { warn "Invalid value for realmonth: $realmonth\n"; }