Ответ 1
Выражение в Perl 6 анализируется как termish
вещи с infixish
вещами между ними. termish
, в свою очередь, определяется как ноль или более prefixish
вещей, за которым следует сам термин, за которым следует ноль или более postfixish
вещей. postfixish
принимает все:
- Вызов метода (например,
.foo
) - Операторы Postfix (например,
++
) - Операторы postcircumfix (например,
[42]
в@a[42]
) - Выполнение гипер (
>>
) на них для распределения их по структуре данных
Поскольку он просто ищет нуль или более из них, вы можете свободно перемежать вызовы методов и индексы хэша и массива. Это объясняет, почему @weekdays.antipairs.hash{'Sunday'}
отлично разбирается (и почему @weekdays.antipairs.hash<Sunday>
также будет работать, и даже @weekdays.antipairs.hash<Sunday>.say
тоже хорошо).
Что касается .
, грамматика просто принимает и игнорирует a .
перед postfix
или postcircumfix
. Здесь немного вырезанная версия синтаксического анализатора, что я немного пояснил, что это за штуки.
token postfixish {
<!stdstopper>
# If we're not in a string interpolation, allow unspace (that's
# where you write '\ ++', for example, allowing spreading
# postfixish things over multiple lines).
[ <!{ $*QSIGIL }> [ <.unsp> | '\\' ] ]?
# Here we match the >> for doing a hyper. Note that it accepts
# but disregards a '.' before it. It not captured at all and
# doesn't affect the code that is compiled.
[ ['.' <.unsp>?]? <postfix_prefix_meta_operator> <.unsp>?]**0..1
[
| <OPER=postfix>
# When there'd be no confusion with a method call, a '.' is
# also accepted and disregarded before a postfix operator
| '.' <?before \W> <OPER=postfix> ## dotted form of postfix operator (non-wordy only)
| <OPER=postcircumfix>
# Ditto here for recognized postcircumfixes
| '.' <?[ [ { < ]> <OPER=postcircumfix>
| <OPER=dotty>
| <OPER=privop>
]
}
Таким образом .
в этом контексте вообще ничего не значит. Парсер просто принимает его, а затем переходит к поиску того, на что он действительно заботится в этот момент.
Еще одна вещь, которую стоит отметить, это то, что операторы postfix и postcircumfix работают после точечного термина, работающего на $_
. Таким образом:
my @xs = 1..10;
.++ for @xs;
say @xs;
Будет производить:
[2 3 4 5 6 7 8 9 10 11]
Вот пример postcircumfix:
my %h = a => 1, b => 2, c => 3;
say .<a> + .<c> given %h;
Который дает 4
.
Синтаксис Perl 6 обычно разработан, чтобы упростить перенос кода из одной формы в другую и принятие .
в местах, где это не требуется строго, это немного (так что можно было бы рефакторировать, чтобы say %h1.<a> + %h2.<b>;
и синтаксический анализатор будет в порядке с ним). Также может быть полезно для учебных целей рассмотреть %h<a>
short для %h.<a>
, что, в свою очередь, сделает .<a> given %h
немного меньше сюрприза.
Дополнительное пространство, предоставляемое .
может также помочь в ясности, особенно если нужно было складывать несколько постфиксных файлов, и может даже - если расширение языка по какой-либо причине решит определить некоторые "интересные" термины или операторы постфикса, - это средство для устранения неоднозначности.