Отладка кода Erlang иногда бывает сложной, особенно в случае ошибок badmatch
. В целом, два хороших принципа:
- Сохраняйте функции короткими
- Используйте возвращаемые значения напрямую, если можете, вместо привязки временных переменных (это даст вам преимущество в получении
function_clause
ошибок и т. Д., Которые более информативны)
При этом использование отладчиков обычно требуется, чтобы быстро докопаться до ошибок. Я рекомендую использовать отладчик командной строки, dbg
, вместо графического debugger
(это намного быстрее, когда вы знаете, как его использовать, и вам не нужно переключать контекст с оболочки Erlang на GUI ).
Учитывая предоставленное вами примерное выражение, часто случается так, что у вас есть больше, чем просто переменные, назначаемые другим переменным (что абсолютно необязательно в Erlang):
run(X, Y) ->
X = something(whatever),
Y = other:do(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,nonode@nohost,29}]}
3> dbg:tpl(my_module, something, x). % tpl = trace local functions as well
{ok,[{matched,nonode@nohost,1},{saved,x}]}
4> dbg:tp(other, do, x). % tp = trace exported functions
{ok,[{matched,nonode@nohost,1},{saved,x}]}
5> dbg:tp(my_module, run, x). % x means print exceptions
{ok,[{matched,nonode@nohost,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:do(more_data)
(<0.72.0>) returned from other:do/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
ошибки или что-то гораздо более сложное.
Надеюсь, все это будет проще, когда Erlang R15 выйдет с номерами строк в исключениях!