Ответ 1
Положение, в котором //g
остановлено, сохраняется в магии, добавленной в скаляр, против которой было выполнено сопоставление.
$ perl -MDevel::Peek -e'$_ = "abc"; Dump($_); /./g; Dump($_);'
SV = PV(0x32169a0) at 0x3253ee0
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x323bae0 "abc"\0
CUR = 3
LEN = 10
COW_REFCNT = 1
SV = PVMG(0x326c040) at 0x3253ee0
REFCNT = 1
FLAGS = (SMG,POK,IsCOW,pPOK)
IV = 0
NV = 0
PV = 0x323bae0 "abc"\0
CUR = 3
LEN = 10
COW_REFCNT = 2
MAGIC = 0x323d050
MG_VIRTUAL = &PL_vtbl_mglob
MG_TYPE = PERL_MAGIC_regex_global(g)
MG_FLAGS = 0x40
BYTES
MG_LEN = 1
Это означает, что единственный способ наблюдения, который наблюдается в примере backticks, - это то, что оператор соответствия сопоставлен с одним и тем же скаляром все четыре раза, когда он был оценен! Как это возможно? Это потому, что backticks является одним из операторов, использующих TARG.
Создание скаляра относительно дорого, так как требует до трех распределений памяти! Для повышения производительности скаляр под названием TARG связан с каждым экземпляром некоторых операторов. Когда оператор с TARG оценивается, он может заполнить TARG значением, возвращаемым и возвращающим TARG (вместо выделения и возврата нового).
"И что?", спросите вы. В конце концов, вы уже продемонстрировали, что назначение скаляру сбрасывает позицию соответствия, связанную с этим скаляром. То, что должно произойти, но это не для обратных сигналов.
Магия не только позволяет привязывать информацию к переменной, но также присоединяет функции, которые будут вызываться при определенных условиях. Магия, добавленная //g
, добавляет функцию, которая должна вызываться после изменения скаляра (что указано флагом SMG
в дампе выше). Эта функция - это то, что очищает позицию, когда значение присваивается скаляру.
Оператор присваивания правильно обрабатывает магию, но не оператором backticks. Он не ожидает, что магия была добавлена в его TARG, поэтому он не проверяет, есть ли там, поэтому функция, которая очищает позицию соответствия, не имеет значения.