Что означает точка перед постфиксом или постфиксом в Perl 6? - PullRequest
0 голосов
/ 05 мая 2018

В Perl doc есть раздел о .postfix / .postcircumfix , там написано, что

В большинстве случаев точка может быть помещена перед постфиксом или постфиксом:

my @a;
@a[1, 2, 3];
@a.[1, 2, 3]; # Same

Технически, не настоящий оператор; это специальный синтаксис в компиляторе.

Я попробовал себя:

> my @a = 1,2,3,4,5
> @a[1]  # 2
> @a.[1] # 2

> my %a = Perl => 6, Python => 3, PHP => 7
> %a<Perl>  #6
> %a.<Perl> #6

> my @weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
> @weekdays.antipairs.hash{'Sunday'}  # 6, I expected it to be syntax wrong, but it did work!
> @weekdays.antipairs.hash.{'Sunday'} # 6, seems visual clarity or brevity

Итак, что означает точка перед постфиксом или постфиксом в Perl 6? Как же он это сделал? Мне интересно об этом. Спасибо.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Это действительно имеет значение, когда у вас есть саб, который возвращает Callable.

sub foo { 'hello' }
sub bar { &foo; }
bar.WHAT # (Sub)
bar().WHAT # (Sub)
bar.().WHAT # (Str)
bar()().WHAT # (Str)
bar().().WHAT # (Str)
bar.().().WHAT # No such method 'CALL-ME' for invocant of type 'Str'
0 голосов
/ 05 мая 2018

Выражение в Perl 6 анализируется как termish вещи с infixish вещами между ними. termish в свою очередь определяется как ноль или более prefixish вещей, за которыми следует сам термин, за которым следует ноль или более postfixish вещей. postfixish принимает все:

  • вызовы методов (например, .foo)
  • Операторы постфикса (например, ++)
  • Операторы Postcircumfix (например, [42] in @a[42])
  • Выполнение гипер (>>) над ними для распределения их по структуре данных

Поскольку он просто ищет ноль или более из них, вы можете свободно чередовать вызовы методов и индексы хешей и массивов. Это объясняет, почему @weekdays.antipairs.hash{'Sunday'} хорошо анализирует (и почему @weekdays.antipairs.hash<Sunday> также будет работать, и даже @weekdays.antipairs.hash<Sunday>.say тоже хорошо).

Что касается ., грамматика просто принимает и игнорирует . перед 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's 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> сокращенным от %h.<a>, что, в свою очередь, сделает .<a> given %h немного менее неожиданным.

Дополнительное пространство, предоставляемое ., также может помочь ясности, особенно если нужно было сложить несколько постфиксов, и даже может - если расширение языка по какой-то причине решит определить некоторые «интересные» термины или операторы постфикса - служить как средство устранения неоднозначности.

...