2012-07-04 3 views
6

Я знаю о том, что [email protected] является глобальной переменной, до сих пор я не могу понять, почему мне нужно локализовать ее перед использованием eval:

Например:

eval { SOME_FUNC_THAT_MAY_DIE(); }; 
if ([email protected]) { 
    print "An error occured!\n"; 
} 

Единственным возможным вещь, о которой я могу думать, если какой-нибудь обработчик сигнала вызовет die в то же самое время, я попытаюсь прочитать [email protected], что мне здесь не хватает?

ответ

12

Причина сказать local [email protected] перед вызовом eval, чтобы не наступить на ваш звонившего [email protected]. Грубо для подпрограммы изменить любые глобальные переменные (если это не одна из заявленных целей подпрограммы). Это не проблема с кодом верхнего уровня (не внутри любой подпрограммы).

Кроме того, на старых Perl, любой eval вызывается при уничтожении объекта будет затирать глобальный [email protected] (если объект разрушается, потому что исключение бросали из eval блока), если [email protected] не был локализован первым. Это было fixed in 5.14.0, но многие люди все еще используют старые Perls.

9

Модуль документация Try::Tiny дает обоснование (а также обеспечить альтернативу):

При запуске блока Eval и он преуспевает, $ @ будет очищен, потенциально затирание ошибки, которая в настоящее время пойманы. Это вызывает действие на расстоянии, устраняя предыдущие ошибки, которые ваш вызывающий абонент еще не обработал. $ @ должен быть правильно локализован перед вызовом eval, чтобы избежать этой проблемы. Более конкретно, $ @ сбивается в начале eval, что также делает невозможным захват предыдущей ошибки перед тем, как вы умрете (например, при создании объектов исключений со стеками ошибок).
+0

Причина, по которой я нашел это сообщение, была именно потому, что я не совсем понял этот параграф в документации Try :: Tiny. Что означает «потенциальная сбой ошибки, которая в настоящее время улавливается»? ;-) –