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.



2011-04-26 00:53:16 lykich

Thanks




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: