Определение подпрограмм

Определение подпрограммы состоит из нескольких частей. Сперва следует декларатор sub, указывающий начало определения подпрограммы. Затем - необязательное имя и необязательная сигнатура. И наконец - тело подпрограммы: ограниченный фигурными скобками блок кода. Этот код выполняется каждый раз при вызове подпрограммы.

К примеру, в коде:

    sub panic() {
        say "Oh no! Something has gone most terribly wrong!";
    }

... определена подпрограмма с именем panic. Ее сигнатура отсутствует, а тело состоит их единственного оператора say.

По умолчанию, подпрограммы ограничена областью лексической видимости, как и любая переменная объявленная с помощью my. Это подразумевает, что подпрограмма может быть вызвана, только в границах той области видимости ( Как правило это блок кода ), внутри которой она была определена. Чтобы подпрограмма стала доступной внутри всего пакета используется декларатор (ключевое слово) our:

    {
        our sub eat() {
            say "om nom nom";
        }

        sub drink() {
            say "glug glug";
        }
    }

    eat();    # om nom nom
    drink();  # fails, can't drink outside of the block

our также делает подпрограмму видимой вне пакета или модуля:

    module EatAndDrink {
         our sub eat() {
             say "om nom nom";
         }

         sub drink() {
             say "glug glug";
         }
    }
    EatAndDrink::eat();    # om nom nom
    EatAndDrink::drink();  # fails, not declared with "our"

Чтобы подпрограмма стала доступна в другой области видимости, используется экспорт (см. Экспортирование).

Подпрограммы в Perl 6 представляют собой объекты. Их можно передавать и хранить в составе структур данных, а так производить те же действия, что и по отношению к другим данным. Дизайнеры языков программирования часто называют их подпрограммами первого класса. Они являются такими же основополагающими для использования в языке, как и хэши или массивы.

Подпрограммы первого класса позволяют решать сложные задачи. Например, для создания небольшого ASCII рисунка с изображением танцующих фигур, возможно построение хэша, ключами которого будут названия движений в танце, а значениями - анонимные подпрограммы. Допустим, что пользователи могут вводить названия списки движений ( возможно с коврика для танцев или другого экзотического устройства). Как можно организовать легко изменяемый список движений, а также возможно безопасно сделать проверку вводимых пользователем названий движений на предмет допустимых ? Возможно следующая структура программы станет отправной точкой для достижения результата:

    my $dance = '';
    my %moves =
        hands-over-head => sub { $dance ~= '/o\ '   },
        bird-arms       => sub { $dance ~= '|/o\| ' },
        left            => sub { $dance ~= '>o '    },
        right           => sub { $dance ~= 'o< '    },
        arms-up         => sub { $dance ~= '\o/ '   };

    my @awesome-dance = <arms-up bird-arms right hands-over-head>;

    for @awesome-dance -> $move {
        %moves{$move}.();
    }

    say $dance;

На основании вывода этой программы, вы сможете убедиться что танец YMCA [1] также плохо выглядит в ASCII виде, как и в реальной жизни.



[1] Возможно имеется в виду Y.M.C.A.