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


Автор: korob2001 29.4.2003, 23:35
Всем доброго времени суток!

Товарищи, помогите пожалуйста понять для чего нужен eval? Если можно приведите короткий пример с ним и поясните какую роль играет eval в нём.
У меня такое чувство что я здесь один задаю вопросы. withstupid.gif
Заранее благодарен,
Денис

Автор: acp 30.4.2003, 08:02
Цитата
У меня такое чувство что я здесь один задаю вопросы

Угу. Т.к. можно увидеть, что наиболее развитые подфорумы на этом форуме - по Дельфи и С.

Цитата
для чего нужен eval?

Ну вообщем, реально eval IMHO нужен только для работы с ошибками, т.е. выполняет роль блока
Код

try
except
end;

в Delphi.

Функция выполняет кусок кода, т.е. просто как-бы представляет собой отдельную процедуру.

Код

eval
{
 #А здесь твой код. Если во время выполнения этого кода
 #произойдёт ошибка, то просто произойдёт выход
 #из блока eval. Программа основная продолжит работу
}

Автор: HalkaR 30.4.2003, 15:57
Сколь я понял, при помощи eval можно перхватывать ошибки в кусках кода.
НАпример в Perl Coocbook присутствует такой пример
Код
if(eval "require mod"){
Обработка ошибки}

Автор: korob2001 1.5.2003, 15:15
Если я правельно понял, то eval даёт эфект наподобие функции warn, но для перехвата ошибки в блоке.

Автор: Guest_test 6.5.2003, 12:36
Eval часто бывает весьма полезен. Напр. прочитываем файл, содержащий строки типа
var = value
var2 = value2
while(<FILE>) {
chomp;
if (s/ *= */=/) {
my ($var,$value) = split(' *= *');
# Заполняем переменные значениями
eval ("\$$var = \'$value\'");
}
}
Без eval - было бы заморочно

Автор: aleksnn 28.4.2005, 04:15
Поднял тему и прошу korob2001 ответь на свой вопрос.
Добавлено @ 04:15
Поднял тему и прошу korob2001 ответь на свой вопрос.

Автор: korob2001 28.4.2005, 09:24
smile Какая тема.
Поясню на примере. Допустим мы принимаем от пользователя числа и делим их, если пользователь попытается разделить первое число на 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, так же у этого блока своя область видимости как и у обычного блока, т.е. если испоьзовать лексические переменные, то они будут видны в этом блоке.
Впринципе это и есть блок.

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

Удачи.

Автор: Гость_frenky 29.4.2005, 00:45
• ее — показывает, что правый аргумент команды s/.../…/ — это строковое выражение, которое надо
вычислить и выполнить как фрагмент кода (через функцию eval). В качестве текста для подстановки
используется возвращаемое значение — возможно, после процесса интерполяции

Автор: Гость_frenky 29.4.2005, 00:45
• (?{код}) — условие (мнимый символ), которое всегда выполняется. Сводится к выполнению команд
Perl в фигурных скобках. Вы можете использовать эту конструкцию, только если в начале сценария
указана команда use re 'eval'. При последовательном соотнесении текста и шаблона, когда Perl доходит
до такой конструкции, выполняется указанный код. Если полного соответствия для оставшихся
элементов найти не удалось, то при возврате левее данной точки шаблона вычисления, проделанные с
локальными переменными, откатываются назад. (Условие является экспериментальным. В
документации, прилагаемой к Perl, можно найти довольно детальное рассмотрение (с примерами)
работы этого условия и возможных трудностей в случае его применения.)

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