Perl 6 / все про operators

Новая «периодическая» таблица операторов

Mark Lentczner обновил таблцу операторов Perl 6.

Новая версия основана на текущем состоянии языка, описанном в третьей главе документации Synopsis 3: Perl 6 Operators и файле грамматики STD.pm. Первая версия таблицы появилась в 2004 году.

grammar, operators — 17 февраля 2009

Оператор интервала

Оператор диапазона .. формирует интервал с заданными границами:

my @hours = 0..24;
my @minutes = 0..60;

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

my @hours = 0..^24;
my @minutes = 0..^60;

Диапазоны, в которых верхняя граница меньше нижней, всегда возвращает пустой интервал.

operators, .. — 10 мая 2008

Оператор конкатенации

Оператор ~ «складывает» строки, составляя из двух одну:

say $month ~ ' ' ~ $year;

Оператор конкатенации — это инфикс, и он имеет тот же вид, что и префиксный оператор ~ перевода в строковый контекст.

В грамматике Perl 6 определено правило для инфиксного оператора ., который при использовании порождает сообщение о том, что такое вид оператора конкатенации устарел и следует использовать ~.

operators, ~ — 9 мая 2008

Инкремент строк

Операторы автоинкремента и автодекремента работают аналогично траниционным операторам ++ и --, но есть интересная особенность, когда эти операторы применяют к строкам.

Будучи примененными к строкам, операторы изменяют хвостовую часть строки, делая попытку увеличить или уменьшить ее на единицу.

Если в строке стоит целое число, то изменяется оно:

my $event = "YAPC::Russia 2008";
$event++;
say $s; # YAPC::Russia 2009

Если при этом оказывается, что после числа есть точка, то изменяется часть, находящаяся перед ней:

my $filename = "img001.gif";
while ($filename.:e) {
    unlink $filename;
    $filename++;
}

Аналогично изменяется целая часть дробного числа:

my $pi = "π = 3.14";
$pi--;
say $pi; # π = 2.14

Инкремент и декремент строк, в которых нет чисел, изменяет последний символ таким образом, что он заменяется следующим по порядку.

my $abc = "abc";
$abc++; # abd

После того, как достигнут последний символ в интервале, символ заменяется первым из этого интервала, и происходит перенос в следующий разряд, то есть изменяется предыдущий символ.

Порядок символов в интервалах соответствует последовательностям символов в юникоде, например: 0..9, A..Z, a..z, Α..Ω, α..ω, א..ת.

operators, ++, -- — 8 мая 2008

Немного о тернарном операторе

Если заглянуть в файл с описанием грамматики Perl 6 STD.pm, то можно найти интересные особенности тернарного оператора.

token infix:sym<?? !!> ( --> Conditional) {
    '??'
    <.ws>
    <EXPR(%conditional)>
    [ '!!' ||
        [
        || <?before '='> <.panic: "Assignment not allowed within ??!!">
        || <?before '::'> <.panic: "Please use !! rather than ::">
        || <?before <infix>>    # Note: a tight infix would have parsed right
           <.panic: "Precedence too loose within ??!!; use ??()!! instead ">
        || <.panic: "Found ?? but no !!; possible precedence problem">
        ]
    ]
    {*}
}
 
token infix:sym<?> ( --> Conditional)
    { <sym> <obs('?: for the conditional operator', '??!!')> }

В грамматику включена проверка на то, чтобы второй разделитель не был :: (таким он был в ранних реализациях Perl 6).

Существует и проверка на то, чтобы не использовался старый синтаксис Perl 5 с одним знаком вопроса. (В Perl 6 оператор ? используется для переключения в булевый контекст.)

operators, ternary — 7 мая 2008

Операторы повтора x и xx

Операторы x и xx повторяют свой аргумент заданное число раз. Отличие между ними в том, что x всегда считает левый операнд строкой, и возвращает строку, а xx рассматривает аргумент в списочном контексте, и возвращает список.

my $item = '*';
say $item x 5; # *****
my @list = 1, 2;
say @list xx 2 # печатает список ((1, 2), (1, 2)) как 1212

Если запрошенное число повторов меньше единицы, возвращаются соответственно, пустая строка и пустой список.

Списочный вариант оператора допускает создание lazy-списков бесконечной длины:

my @letters = 'a'..'z';
.print for @letters xx *;

Этот код печатает бесконечную последовательность букв.

operators, x, xx — 6 мая 2008