Иллюстрированный самоучитель по Perl



         

Замыкания


Для заполнения массива ecaiendar нам потребуется функция, которая по заданному году, месяцу и дню месяца вычисляет соответствующий день недели. Читатель может сам написать свой вариант функции, может быть, более изящный. Мы предлагаем наш вариант (пример 9.1) с основной целью: рассказать об одном интересном свойстве анонимных подпрограмм. Кроме того, он правильно работает для любого года нашей эры.

Вычисление дня недели основано на том, что:

  • 1 января 1 года нашей эры было понедельником;
  • каждый год, номер которого делится на 4, является високосным, за исключением тех номеров, которые делятся на 100 и не делятся на 4.
  • (Вопросы создания функций пользователем рассмотрены в части 11.)

    sub GetDay (

    my $year = shift;

    my @days = (Q,31,59,90,120,151,181,212,243,273,304,334);

    my @week = ("Monday","Tuesday","Wednesday","Thursday",

    "Friday","Saturday","Sunday"); my $previous_years_days = ($year -1 ).*365 + int (($year-l) /4)

    - int(($year-l)/100) + int(($year-l)/400); return sub { my ($month, $day)=@_;

    my $n « $previous_years_days + $days[$month-l] + $day -1; $n++ if ($year%4 == 0 and $year%100 != 0 or

    $year%400 == 0 and $month > 2) ; return $week[$n%7]; } };.

    Аргументами функции GetDay о являются номер года, номер месяца и номер дня месяца. Внутри тела функции им соответствуют переменные $уеаг, $month и $day. Функция подсчитывает число дней $п, прошедших с 1 января 1 года. Остаток от деления этого числа на 7 — $п%7 — определяет день недели как элемент массива $week[$n%7].

    Необходимые пояснения к тексту

    Для передачи параметров в подпрограмму используется предопределенный массив @_. Встроенная функция shift•() без параметров, вызванная внутри подпрограммы, возвращает первый элемент массива @_ и осуществляет сдвиг всего массива влево, так, что первый элемент пропадает, второй становится первым и т.д. Элемент массива $days[$l] равен суммарному числу дней в первых i месяцах не високосного года, i = (0..11). В переменной $previous_years_days запоминается вычисленное значение общего количества дней, прошедших с 1 января 1 года до начала заданного года.




    Содержание  Назад  Вперед