Я думаю, что вы делаете предположения, которые не верны. PSH интерпретируется, поэтому, когда создается блок кода, он просто содержит исходный код. Когда он позднее оценивается, любые используемые им переменные будут просматриваться обычным образом PSH: сначала в текущей области, а затем в каждой внешней области, пока не будет найдена переменная с соответствующим именем.
Когда таймер запускает свое событие, он выполняет блок кода и, таким образом, ищет $i
. Который находится во внешней области видимости со значением 2.
Во втором случае, если вы просто используете блок кода напрямую (удалите вызов GetNewClosure
), то при втором выполнении вы получите 2.