Строчная интерполяция в Perl6

Ozzy спросил: 28 марта 2018 в 03:55 в: perl6

Мне трудно понять, почему оператор

say "\c500";

выводит символ "Ǵ" на моем экране, как ожидалось, в то время как следующие операторы дают мне сообщение об ошибке во время компиляции ( "Unrecognized \ c character"):

my $i = 500;
say "\c$i";

, хотя

say "$i"; # or 'say $i.Str;' for that matter

создает "500" (с "$ i" .WHAT указывающий тип Str).


2 ответа

Есть решение
jjmerelo ответил: 28 марта 2018 в 04:36

Вам нужно будет использовать $i.chr, что описано здесь. \c обрабатывается специально внутри строк и, по-видимому, не допускает ничего, что не является литералом.

Ozzy ответил: 28 марта 2018 в 06:08
Спасибо за обходной путь. Между тем мое концептуальное понимание, возможно, немного улучшилось. Я предполагаю, что конструкция \ c [...] также является структурой интерполяции строк, чья обработка предшествует обработке $ i, вызывая конфликт. Изначально я думал, что \ c [...] обрабатывается функцией say, но, похоже, это не так, поскольку say '\c500' просто возвращает \c500.
Jonathan Worthington ответил: 28 марта 2018 в 06:53
\c500 является escape-последовательностью, немного похожей на \n. В строке в двойных кавычках, поскольку вызовы метода интерполируют, $i.chr() также будет интерполировать.
Brad Gilbert ответил: 28 марта 2018 в 08:59

Анализатор строковых литералов в Perl 6 является типом языка, специфичного для предметной области.

В основном то, что вы пишете, компилируется аналогично остальному языку.

"abc$_"
&infix:«~»('abc',$_.Str)

В случае \c500 вы можете просмотреть его как константу времени компиляции.

"\c500"
(BEGIN 500.chr)

На самом деле это больше похоже на:

(BEGIN 500.HOW.find_method_qualified(Int,500,'chr').(500))

За исключением того, что компилятор для строковых литералов фактически пытается скомпилировать его в абстрактное синтаксическое дерево, но не может, потому что там нет Код не был добавлен для обработки этого случая \c.
Даже если он был, \c эффективно скомпилирован для выполнения во время BEGIN, что раньше $_ имеет значение.


Также \c используется для более чем .chr

"\c9" eq "\c[TAB]" eq "\cI" eq "\t"

(Обратите внимание, что \cI представляет символ, который вы получите, набрав Cntrl + Alt + i в платформа posix)

Так какой из них должен \c$_ компилироваться в?

$_.chr
$_.parse-names
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.index($_).succ.chr

Если вы хотите .chr вы можете напишите это как одно из следующего. (пробелы добавлены там, где они разрешены)

"abc$_.chr( )def"
"abc{ $_.chr }def"
"abc{ .chr }def"
'abc' ~ $_.chr ~ 'def'
Ozzy ответил: 29 марта 2018 в 04:28
Это поучительно. Спасибо. - Переваривая ваш ответ, я прочитал, что .parse-names устарел в пользу .uniparse; только для тех, кто может прочитать это в будущем.