调试Erlang代码有时可能会非常棘手,尤其是处理badmatch
错误。在一般情况下,两个很好的指导方针,以保持有:
- 保持功能,短期直接
- 使用返回值如果可以的话,而不是绑定临时变量(这会给你越来越
function_clause
错误等,这是方式的好处更多的信息)
这就是说,使用调试器通常需要快速到达错误的底部。我建议使用命令行调试器dbg
而不是图形的debugger
(当你知道如何使用它时,它的速度会更快,而且你不必从Erlang shell切换到GUI)。
给你提供的样品表达,情况往往是,你拥有的不仅仅是变量更被分配到其他变量(这是在二郎山完全没有必要):
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,[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
模块的完整文档可以在here找到。
鉴于这两个something/1
和other:do/1
总是返回OK,下面会发生:
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这一呼吁之前发生的事情。
熟练使用命令行调试器将为您节省大量时间,您是否调试简单(但棘手!)badmatch
错误或更复杂的东西。
希望在Erlang R15出现异常行号的情况下,所有这些都会变得更简单!
请选择哪个答案解决您的问题,如果有的话。 –