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
Автор: WarFair