Perl6 — Работа с функциями

от автора

1. Особенности работы с переменными и литералами в Perl6
2. Perl6 — Операции над переменными, анонимные блоки
3. Perl6 — Условные операторы, циклы

Настало время рассмотреть работу с функциями. По этой теме в Perl6 есть несколько изменений относительно пятого, как например именованные параметры, или возможность создания главной функции в скрипте, но начнем по порядку:

В Perl6 функции объявляются конструкцией

sub SubName($a, $r, $g, $s)  {      //SomeWork  }

Имеется возможность указывать типы получаемых параметров

sub SubName(Int $a)  { SomeWork(); } 

однако, в случае если функция будет вызвана с аргументом другого типа, то выполнение скрипта будет остановлено с ошибкой. Так же количество передаваемых аргументов должно совпадать с количеством аргументов при объявлении функции.

Вызов функции происходит с помощью конструкций

f(10, True, "str", {say "closure";}); f 20, False, "aaa", 9.999;

Так же как и в C++ мы можем делать перегрузку функций, однако для каждой функции необходимо будет добавлять слово ‘multi’:

multi sub f(Int $a) {say 'Int';}; multi sub f(Str $a) {say 'Str';}; f("string"); f(100500);

В результате будет выведено на экран:

Str Int

Для указания области видимости функций используются слова my и our — соответственно видимость в той области где функция была объявлена и глобальная область видимости.
Можно указывать тип значения, возвращаемого функцией:

my Int sub func($a)  {return $a+1;}

В случае не совпадения указанного при объявлении типа и типа возвращаемого значения во время работы, скрипт будет остановлен с ошибкой о несоответствии типов.
Параметрам функции можно дополнительно указывать, можно ли изменять эти параметры внутри функции:

sub f($a is rw)  {      $a*=10;  } my $z = 5; f($z); say $z;

В результате будет выведено число 50
Так же в синопсах указано, что функция может возвращать lvalue значение:

my $b = 10; sub f() is rw  {      return $b;  } f() = 5; say $b;

В результате на экране должно будет выведено число 5, однако в последней версии (12.09) возможность исользования lvalue значений ещё не готова, и в моем случае выдавалась ошибка при компиляции.
В Perl6 появилась возможность использования именованных параметров:

my sub func(:$name1, :$name2, :$name3)  {      say $name1, ' ', $name2, ' ', $name3;  } my $a = 10; func :name2<text2>, :name1<1+2+$a>, name3=>$a; my %hash = {name3=>'text3', name2=>'text2', name1=>'text1'}; func |%hash;

В результате на экране будет выведено:

1+2+$a text2 10 text1 text2 text3

Если в качестве параметра передавать не |%hash а просто %hash, то тогда функция будет принимать его как позиционный аргумент — в нашем случае у функции нет позиционных элементов, поэтому работа скрипта будет завершена с ошибкой.
Так же для указания именованного аргумента можно использовать конструкцию :arg($value). Разница между этим вариантом и :arg<$value> в том, что во втором случае значение переменной не будет подставляться, и в итоге в первом случае мы получаем значение переменной $value, а во втором случае получаем строку ‘$value’.
В дополнении можно использовать необязательные параметры:

sub HaveArgument($arg?)  {      if $arg.defined       {           say 'yes';       }      else       {           say 'no';       }  } HaveArgument; HaveArgument 10;

В результате получим строки

no yes

Для создания функций с переменным количеством аргументов, как было в perl5, можно воспользоваться конструкцией:

sub Counter(*@arg)  {      say @arg.elems;  } Counter(1, 2, 3); Counter;

В результате будет выведено два числа: 3 и 0
Перед *@ args можно указывать позиционные элементы:

sub Counter($a, *@arg)  {...}

Функция MAIN:
В Perl6 появилась возможность создания функции MAIN, как на подобии C++, однако, есть несколько отличий. Нарпимер вне тела функции можно делать вызовы других функций, и эти вызовы будут совершены раньше чем начнет выполняться функция MAIN:

sub MAIN()  {      say "MAIN!";      say "Hello!";  }  say "123!";

В результате на экране мы увидим строки

123! MAIN! Hello!

Так же для функции MAIN можно задавать входные параметры, которые будут являться обязательными параметрами при вызове скрипта на исполнение:
Если содержимое скрипта:

sub MAIN($arg1, $arg2)  {      say "MAIN!";      say $arg1, ' ', $arg2;  } say "123!";

И вызвать скрипт без параметров, то в результате мы получим на экране текст:

123! Usage:   /home/warfair/Рабочий стол/script.p6 <arg1> <arg2>

Заметте, что при этом была вызвана функция say «123!», находящийся вне тела какой либо функции, и только после этого, произошла ошибка вызова MAIN.
Ссылку на функцию можно сохранить в переменную с помощью конструкции

sub MySub() {...}; my $var = &MySub;

Можно создавать анонимные функции и сохранять ссылки на них в скалярных переменных

my $r = sub ($a)  {      return $a*2;  } say $r(2); 

В результате мы увидим 4

ссылка на оригинал статьи http://habrahabr.ru/post/154997/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *