Наиболее
простой метод отладки - применение средства printlevel
, позволяющее проследить за выполнением
программы. Это глобальная переменная, которая
при начальной загрузке Maple равна 1. Если присвоить
ей большее целое значение, то при выполнении
процедуры на экран будут выводиться
последовательность присвоений, вход и выход из
процедуры с перечислением значений параметров
процедуры (трассировка процедуры). Величина
переменной printlevel определяет уровень (глубину)
вложенных процедур, которые будут
трассироваться при выполнении программы. Для
того, чтобы читалась процедура с глубиной
вложения n нужно задать printlevel:=n*5. Применим
трассировку для выяснения ошибки в записанной
выше процедуре out.
> out:=proc(x::list)
local v;
v:=x[1];
map(y->y^v,x);
### WARNING: `v` is a lexically scoped local
end;
Зададим для переменной printlevel значения,
достаточное, чтобы читались процедуры второго
уровня вложения.
> printlevel:=10;
> out([2,3,4,5]);
{--> enter out, args = [2, 3, 4, 5]
{--> enter unknown, args = 2
<-- exit unknown (now in out) = 4}
{--> enter unknown, args = 3
<-- exit unknown (now in out) = 9}
{--> enter unknown, args = 4
<-- exit unknown (now in out) = 16}
{--> enter unknown, args = 5
<-- exit unknown (now in out) = 25}
<-- exit out (now at top level) = [4, 9,
16, 25]}
Из распечатки видно, что во вложенную
процедуру не передается значение переменной v.
Если в программе встречается системная
ошибка, то при значении printlevel>3 Maple распечатает
на экране параметры всех процедур, выполняемых
на данный момент, значения локальных переменных
и команду, которая выполнялась при возникновении
ошибки.
Приведем пример с ошибкой - деление на
ноль.
> ### WARNING: `z` is implicitly
declared local
f:= proc(x) local y; z:=5; g(x,y); end;
Warning, `z` is implicitly declared local
> g:=proc(z,t) local u,v; u:=0;
v:=t/u; u+v;end;
Зададим переменную printlevel .
> printlevel:=4;
> f(x);
f called with arguments: x
#(f,2): g(x,y)
g called with arguments: x, y
#(g,2): v := t/u;
Error, (in g) division by zero
locals defined as: u = 0, v = v
Для трассировки процедур используются
также команды Maple trace , untrace , которые, в
отличие от выше описанного метода, позволяют
выборочно трассировать некоторые из вложенных
процедур, чтобы исключить громоздкий вывод на
дисплей.
Эти команды могут использовать в
следующих вариантах:
trace(f);
trace(f,g,h,...);
untrace(f);
untrace(f,g,h,...);
где f, g, h, ... - имена процедур, которые будут
трассироваться командой
Команда trace инициирует в течение
выполнения программы вывод на дисплей точек
входа, результат выполнения операторов
программы и точек выхода трассируемой процедуры.
В точках входа выводятся значения фактических
параметров процедур, в точках выхода - значения
возвращаемых функций.
Функция untrace выключает трассировку по
указанным процедурам.
В качестве примера включим трассировку
процедуры g, предварительно установив
> printlevel:=1;
> trace(g);
> f(x);
{--> enter g, args = x, y
<-- ERROR in g (now in f) = division by
zero}
Error, (in g) division by zero
Мы видим, что трассировка при выполнении
процедуры f включена только для вложенной
процедуры g. Если выполняемая процедура будет
вводиться с символом двоеточия в конце команды,
то на дисплей будут выводиться только параметры
в точках входа и выхода процедуры, а результат
выполнения операторов выводиться не будет.
> trace(f,g);f(x):
{--> enter f, args = x
{--> enter g, args = x, y
<-- ERROR in g (now in f) = division by
zero}
<-- ERROR in f (now at top level) =
division by zero}
Error, (in g) division by zero
|