eval
Синтаксис
eval EXPR eval BLOCK
Описание
Функция осуществляет анализ и выполнение выражения EXPR, как если бы оно представляло собой
автономную программу на Perl. Однако выполнение производится в контексте текущей исполняемой программы,
что позволяет использовать любые переменные, подпрограммы и определения форматов, которые используются
в данной программе. Значение, возвращаемое функцией, представляет собой значение последнего выражения
внутри eval. Допускается использование оператора return
как в обычной подпрограмме.
Последнее выражение оценивается в скалярном или списочном контекстах, в зависимости от контекста вызова самой eval.
Если при компиляции или исполнении аргумента eval обнаружена ошибка либо был выполнен оператор
die,
возвращается значение undef, а в переменную $@
помещается текст сообщения об ошибке. Если же ошибок не было, $@ содержит пустую строку.
В случае отсутствия аргумента у функции оценивается содержимое переменной $_. Завершающий символ точки
с запятой, если он присутствует в строке-аргументе, удаляется.
ПРИМЕЧАНИЕ
Имейте в виду, что использование eval не затыкает рот Perl в части вывода сообщений об ошибках в STDERR,
равно как и не переносит тексты предупреждений в переменную $@. Для выполнения любой из этих операций
вы должны использовать механизм $SIG{__WARN__}. См. описание warn.
Обратите также внимание, что, поскольку функция eval перехватывает ошибки, которые в иных
обстоятельствах считаются фатальными, она оказывается полезной для определения системно-ориентированных
особенностей реализации таких механизмов, как socket или symlink. Кроме того, eval представляет собой
ядро механизма перехвата исключений, генерируемых с помощью оператора die.
В случае необходимости вы можете использовать формат eval-BLOCK, чтобы перехватывать ошибки этапа
исполнения программы без необходимости постоянной перекомпиляции кода. В этом случае возникающая ошибка,
как и ранее, помещается в $@. Вот несколько примеров:
# деление на нуль нас больше не пугает!
eval { $answer = $а / $b; }; warn $@ if $@;
# то же самое, хотя не столь элегантно
eval '$answer = $а / $b'; warn $@ if $@;
# ошибка этапа компиляции
eval { $answer = };
# ошибка этапа выполнения
eval '$answer ='; # sets $@
При использовании формы eval {} в качестве ловушки исключений, генерируемых внутри библиотек,
у вас может возникнуть желание не перехватывать все подряд обработчики _DIE_, которые могут
быть установлены в пользовательском коде. В этом случае вы можете использовать конструкцию
local $SIG{_DIE_}, как это показано в приведенном ниже примере:
# перехват деления на нуль
eval { local $SIG{'__DIE__'}; $answer = $a / $b; };
warn $@ if $@;
Необходимо также помнить о том, что обработчики __DIE__ могут сами использовать
die, на
практике это ведет к замене текстов сообщений об ошибках:
# __DIE__ перехватчик может модифицировать сообщения об ошибках
{
local $SIG{'__DIE__'} =
sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x };
eval { die "foo foofs here" };
print $@ if $@; # выводит "bar barfs here";
}
При использовании eval вы должны быть особенно внимательны в тех случаях,
которые описаны ниже:
eval $х; # Случай 1
eval "$x"; # Случай 2
eval '$x' ; # Случай 3
eval { $х }; # Случай 4
eval "\$$x++"; # Случай 5
$$х++; # Случай б
Первый и второй случаи практически идентичны: они выполняют код, хранящийся в переменной $х.
Впрочем, второй вариант содержит излишние двойные кавычки, которые не оказывают влияния на интерпретацию
значения переменной.
Случаи 3 и 4 также подобны друг другу - они запускают на выполнение код '$х',который не делает
ничего, кроме возвращения значения $х. Предпочтительнее использовать вариант 4, который более понятен
при чтении, а также обрабатывается на этапе компиляции, а не во время исполнения программы.
Наконец, вариант 5 используется в тех случаях, когда вам обычно хотелось бы поставить двойные кавычки,
за исключением той ситуации, если вы используете символьную ссылку, как в случае 6.
Thanks
2023-11-16 22:30:18 Svetlana Thank you very useful information
Оставить комментарий:
|
|