Using a BEGIN Block
Does
that mean we’re stuck with
putting the %month_num assignment up at the top of
the script, such that it will be visible everywhere, not just in the
subroutine where it’s needed? No, we’re not stuck with
that. We can use a special trick to make part of our script execute
immediately after the compilation phase, before the normal runtime
stuff happens. That trick is to put that part of our script inside a
block labeled with the special word BEGIN (in all
caps).
Let’s modify that anonymous block enclosing the
&get_seconds subroutine to be a
BEGIN block, and move the
%month_num hash definition from the top of the
script to the inside of that BEGIN block. The
final version of the &get_seconds subroutine,
including its enclosing BEGIN block, will then
look like this:
BEGIN { my %date_seconds;my %month_num = (Jan => 0,Feb => 1,Mar => 2,Apr => 3,May => 4,Jun => 5,Jul => 6,Aug => 7,Sep => 8,Oct => 9,Nov => 10,Dec => 11,);sub get_seconds { # this subroutine accepts a date string of the form # '06/Jul/1999' and a time string of the form '12:14:00' # and returns the number of seconds since the Unix # epoch, as determined by Time::Local's timelocal # function. the subroutine caches conversions of the # date part in %date_seconds in order to improve # performance. my ($date, $time) = @_; my $seconds; if ($date_seconds{$date}) { $seconds = $date_seconds{$date}; } else { my ($day, $mon, $yr) = split /\//, $date; $mon = $month_num{$mon}; $yr = $yr - 1900; ...