Ответ 1
Отладка кода Erlang иногда бывает сложной, особенно в случае ошибок badmatch
. В общем, два хороших принципа:
- Сохраняйте функции короткими
- Используйте возвращаемые значения напрямую, если можете, вместо привязки временных переменных (это поможет вам получить ошибки
function_clause
и т.д., Которые будут более информативными)
При этом использование отладчиков обычно требуется, чтобы быстро докопаться до ошибок. Я рекомендую использовать отладчик командной строки, dbg
, вместо графического, debugger
(это намного быстрее, когда вы знаете, как его использовать, и вам не нужно переключать контекст с оболочки Erlang на GUI).
Учитывая предоставленное вами примерное выражение, часто случается так, что у вас есть не только переменные, назначаемые другим переменным (что абсолютно необязательно в Erlang):
run(X, Y) ->
X = something(whatever),
Y = other:thing(more_data),
Отладке ошибки badmatch
здесь помогает отладчик командной строки:
1> dbg:tracer(). % Start the CLI debugger
{ok,<0.55.0>}
2> dbg:p(all, c). % Trace all processes, only calls
{ok,[{matched,[email protected],29}]}
3> dbg:tpl(my_module, something, x). % tpl = trace local functions as well
{ok,[{matched,[email protected],1},{saved,x}]}
4> dbg:tp(other, do, x). % tp = trace exported functions
{ok,[{matched,[email protected],1},{saved,x}]}
5> dbg:tp(my_module, run, x). % x means print exceptions
{ok,[{matched,[email protected],1},{saved,x}]} % (and normal return values)
Ищите {matched,_,1}
в возвращаемом значении... если бы это было 0
вместо 1
(или более), это означало бы, что ни одна функция не соответствовала шаблону. Полную документацию по модулю dbg
можно найти здесь.
Учитывая, что something/1
и other:do/1
всегда возвращаются нормально, может произойти следующее:
6> my_module:run(ok, ok).
(<0.72.0>) call my_module:run(ok,ok)
(<0.72.0>) call my_module:something(whatever)
(<0.72.0>) returned from my_module:something/1 -> ok
(<0.72.0>) call other:thing(more_data)
(<0.72.0>) returned from other:thing/1 -> ok
(<0.72.0>) returned from my_module:run/2 -> ok
ok
Здесь мы можем увидеть всю процедуру вызова и какие возвращаемые значения были даны. Если мы назовем это с чем-то, что, как мы знаем, потерпит неудачу:
7> my_module:run(error, error).
** exception error: no match of right hand side value ok
(<0.72.0>) call my_module:run(error,error)
(<0.72.0>) call my_module:something(whatever)
(<0.72.0>) returned from my_module:something/1 -> ok
(<0.72.0>) exception_from {my_module,run,2} {error,{badmatch,ok}}
Здесь мы видим, что мы получили исключение badmatch
, был вызван something/1
, но никогда other:do/1
, поэтому мы можем сделать вывод, что сбой произошел до этого вызова.
Опыт работы с отладчиком командной строки сэкономит вам много времени, если вы отлаживаете простые (но сложные!) badmatch
ошибки или что-то гораздо более сложное.