(Переписано после дополнительного тестирования и написания кода).
Это выглядит для меня (и, вероятно, для вас) как ошибка. $/
как-то становится кибошедом при использовании :g
и встроенного блока.
Этот ответ охватывает:
Обнуление задачи
my &debug = {;} # start off doing no debugging
$_ = 'aa';
say m / {debug 1} 'a' {debug 2} /; debug 3; # 「a」
say $/ if m / {debug 1} 'a' {debug 2} /; debug 3; # 「a」
say m:x(2) / {debug 1} 'a' {debug 2} /; debug 3; # (「a」 「a」)
say $/ if m:x(2) / {debug 1} 'a' {debug 2} /; debug 3; # (「a」 「a」)
say m:g / {debug 1} 'a' {debug 2} /; debug 3; # (「a」 「a」)
say $/ if m:g / {debug 1} 'a' {debug 2} /; debug 3; # 「a」 <--- Uhoh
Теперь заставьте debug
сказать что-нибудь полезное и запустите первую пару (без наречия регулярного выражения):
&debug = { say $_, $/.WHICH } # Say location of object bound to `$/`
say m / {debug 1} 'a' {debug 2} /; debug 3; # 「a」
# 1Match|66118928
# 2Match|66118928
# 「a」
# 3Match|66118928
say $/ if m / {debug 1} 'a' {debug 2} /; debug 3; # 「a」
# 1Match|66119072
# 2Match|66119072
# 「a」
# 3Match|66119072
Один и тот же простой результат в обоих случаях. Процесс сопоставления создает объект Match
и придерживается того же объекта.
Теперь два варианта с наречием :x(2)
:
say m:x(2) / {debug 1} 'a' {debug 2} /; debug 3; # (「a」 「a」)
# 1Match|66119936
# 2Match|66119936
# 1Match|66120080
# 2Match|66120080
# 1Match|66120224
# (「a」 「a」)
# 3List|67612624
say $/ if m:x(2) / {debug 1} 'a' {debug 2} /; debug 3; # (「a」 「a」)
# 1Match|66120368
# 2Match|66120368
# 1Match|66120512
# 2Match|66120512
# 1Match|66120656
# (「a」 「a」)
# 3List|67612672
На этот раз процесс сопоставления создает Match
объект и придерживается его в течение одного прохода, затем второй объект сопоставления для второго прохода и, наконец, третий объект сопоставления для третьего прохода, прежде чем он не будет соответствовать третьему 'a'
(и, следовательно, соответствующий debug 2
не не звонят). В конце вызова m.../.../
он создал объект List
и связал с до $/
.
Далее запустим первый из двух случаев :g
:
say m:g / {debug 1} 'a' {debug 2} /; debug 3; # (「a」 「a」)
# 1Match|66119216
# 2Match|66119216
# 1Match|66119360
# 2Match|66119360
# 1Match|66119504
# (「a」 「a」)
# 3Match|66119504
Как и в случае x:(2)
, мы пытаемся в третий раз и терпим неудачу. Но процесс сопоставления не возвращает List
, а вместо этого Match
объект. И это тот, который был создан на третьем проходе. (Что меня удивляет.)
Наконец, есть случай "Uhoh":
say $/ if m:g / {debug 1} 'a' {debug 2} /; debug 3; # 「a」 <--- Uhoh
# 1Match|66119648
# 2Match|66119648
# 1Match|66119792
# 2Match|66119792
# 「a」
# 3Match|66119792
Примечательно, что ожидаемый третий проход не начинается.
Глядя на исходный код компилятора
Вероятно, что изучение соответствующего исходного кода будет полезным. Я напишу об этом здесь, на случай, если это заинтересует вас или других читателей, и если это ошибка, и то, что я пишу, будет интересно тому, кто ее исправит.
Указание блока кода в отведениях регулярных выражений для генерируемого узла AST здесь , который вставляет подузел перед операторами в блоке, который выполняет операцию связывания:
:op('bind'),
QAST::Var.new( :name('$/'), :scope('lexical') ),
QAST::Op.new(
QAST::Var.new( :name('$¢'), :scope('lexical') ),
:name('MATCH'),
:op('callmethod')
)
Мое прочтение вышеизложенного состоит в том, что он вставляет код, который связывает лексический символ $/
с результатом вызова метода .MATCH
для объекта, привязанного к лексическому символу $¢
, непосредственно перед запуском кода в блоке.
do c имеет раздел на $¢
; Я процитирую предложение:
Основное различие между $/
и $¢
заключается в объеме: последний имеет значение только внутри [a] регулярного выражения
Мне остается удивляться, почему существует $¢
и какие существуют другие различия.
Идем дальше ...
Я вижу, что уровень раку .MATCH
. Но это почти ничего не делает. Поэтому я предполагаю, что соответствующий код здесь .
На этом этапе я сделаю паузу. Я мог бы продолжить дальше в более поздней редакции.
Поиск очередей проблем и / или регистрация новой проблемы
Если кто-то придет с ответом в ближайшие несколько дней, демонстрируя, что вы показали не является ошибкой, или уже была подана как ошибка, то достаточно справедливо.
В противном случае, пожалуйста, подумайте о том, чтобы выполнить собственный поиск в очередях проблем и / или начать новую проблему в любой очереди проблем, которую вы считаете наиболее подходящий (по умолчанию /rakudo/rakudo/issues).
Я уже искал четыре очереди проблем github.com, которые я посчитал правдоподобными при написании этого ответа:
Я искал два ключевых слова, которые, как я надеялся, могут раскрыть существующий выпуск («глобальный» и «опубликованный sh»). Нет подходящих проблем. Возможно, вы также можете найти другие ключевые слова, которые, по вашему мнению, может использовать файлер.
Если вы подаете проблему, рассмотрите возможность добавления ваших тестов или моего или другого варианта, преобразованного в стандартные тестовые наборы, если вы знаете, как это сделать.