Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Что такое eval и как с ним работать.


Автор: korob2001 25.6.2005, 22:24
 Поясню на примере. Допустим мы принимаем от пользователя числа и делим их, если пользователь попытается разделить первое число на 0, то программа просто завершится крахом. Например если выполнить такой код:
Код

#!/usr/bin/perl -w
use strict;
my $num1 = 10;
my $num2 = 0;
my $res = 0;
$res = $num1 / $num2;
print $res;

То он закончится такой ошибкой: Illegal division by zero at Untitled line 3., т.е. программа завершилась аварийно. Тепь давай перехватим ошибки при делении и выведем более понятное сообщение и продолжим выполнение программы, перепишем наш код так:
Код

#!/usr/bin/perl -w
use strict;
my $num1 = 10;
my $num2 = 0;
my $res = 0;
eval { $res = $num1 / $num2 };
print $res;

Мы не получим ошибки этапа исполнения, но мы так и не обработали её, просто перехватили. Давай теперь попробуем вывести какое-нить сообщение и подолжим выполнение программы. Если eval перехватил ошибку этапа исполнения, то он сохраняет её в специальную переменную:
$@. Вот и проверим её.
Код

#!/usr/bin/perl -w
use strict;
my $num1 = 10;
my $num2 = 0;
my $res = 0;
eval { $res = $num1 / $num2 };
$res = "Не могу выполнить деление\n" if $@;
print $res;

В итоге мы получим наше сообщение об ошибке, которое будет присвоено переменной $res, в том случае если возникнет исключительная ситуация этапа исполнения. Если изменить значение переменной $num2 на допустимое число, то мы не получим нашего сообщения, а просто получим результат деления.

Всё это хорошо, но у eval есть ещё одна форма eval 'выражение', которая компилирует какой-либо участок кода на лету, на этапе исполнения и перехватует все исключительные ситуации, так же как и первая, но выполняется гораздо медленнее первой, так как она анализирует каждый раз синтаксис. Если кто-то знаком с такими языками как Java, C++, то наверняка знакомы с блоком try {}, eval в Perl выполняет те же функции. 
Вот аналогичный код проверки деления на 0, только выполняется гораздо медленне:
Код

#!/usr/bin/perl -w
use strict;
my $num1 = 10;
my $num2 = 0;
my $res = 0;
eval '$res = $num1 / $num2';
print "Не могу выполнить деление на 0\n" if $@;
print $res;

На самом деле eval { }, это своего рода блок кода из которого можно выходить в любой момент, с помощью return, так же у этого блока своя область видимости как и у обычного блока, т.е. если испоьзовать лексические переменные, то они будут видны в этом блоке.
Впринципе это и есть блок.

Ну вот, вроде основное описал. :rolleyes 

Удачи. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)