Nested Cases
From Erlang Community
| Revision as of 08:09, 2 September 2006 (edit) Rvg (Talk | contribs) ← Previous diff |
Revision as of 08:10, 2 September 2006 (edit) (undo) Rvg (Talk | contribs) Next diff → |
||
| Line 1: | Line 1: | ||
| + | [[Category:Best Practises]] | ||
| This article describes one of the Erlang best practices. It is particularly difficult to trace errors when a programmer used many nested case statements in a single function. | This article describes one of the Erlang best practices. It is particularly difficult to trace errors when a programmer used many nested case statements in a single function. | ||
Revision as of 08:10, 2 September 2006
This article describes one of the Erlang best practices. It is particularly difficult to trace errors when a programmer used many nested case statements in a single function.
Consider the following code fragment that implements a basic operation table:
1: function(Operation,Values) ->
2: case Operation of
3: null ->
4: null;
5: multiply ->
6: case Values of
7: [A,B] when integer(A),
8: integer(B) ->
9: {ok,A*B}
10: end
11: end.
As you can see, it contains a nested case (line 6).If we execute the multiplication operation, the code performs as expected:
(rvg@davinci)5> test:function(multiply,[5,2]).
{ok,10}
Now, let us try an invalid operation:
(rvg@davinci)6> test:function(divide,[5,2]).
=ERROR REPORT==== 25-Dec-2004::20:30:28 ===
Error in process <0.43.0> on node 'rvg@davinci' with exit value:
{{case_clause,divide},[{test,function,2},{shell,exprs,6},{shell,eval_loop,3}]}
** exited: {{case_clause,divide},
[{test,function,2},{shell,exprs,6},{shell,eval_loop,3}]} **
As expected, the shell crashed with a case_clause. Now, let us try the same with invalid multiplication parameters:
(rvg@davinci)7> test:function(multiply,[5,2,3]).
=ERROR REPORT==== 25-Dec-2004::20:33:05 ===
Error in process <0.47.0> on node 'rvg@davinci' with exit value:
{{case_clause,[5,2,3]},[{test,function,2},{shell,exprs,6},{shell,eval_loop,3}]}
** exited: {{case_clause,[5,2,3]},
[{test,function,2},{shell,exprs,6},{shell,eval_loop,3}]} **
As you can see, the reason is still {case_clause,...}. In complex code, you would not easily figure out which case caused the problem. Let us fix the code:
1: function(Operation,Values) ->
2: case Operation of
3: null ->
4: null;
5: multiply ->
6: do_multiply(Values)
7: end.
8:
9: do_multiply([Value1,Value2]) when integer(Value1),
10: integer(Value2)->
11: {ok,Value1*Value2}.
If we pass an invalid operation:
(rvg@davinci)11> test:function(divide,[5,2]).
=ERROR REPORT==== 25-Dec-2004::20:37:54 ===
Error in process <0.60.0> on node 'rvg@davinci' with exit value:
{{case_clause,divide},[{test,function,2},{shell,exprs,6},{shell,eval_loop,3}]}
** exited: {{case_clause,divide},
[{test,function,2},{shell,exprs,6},{shell,eval_loop,3}]} **
You can see that the case clause in function(...) cannot handle the divide atom. If we pass invalid parameters:
(rvg@davinci)12> test:function(multiply,[5,2,3]).
=ERROR REPORT==== 25-Dec-2004::20:38:54 ===
Error in process <0.62.0> on node 'rvg@davinci' with exit value:
{function_clause,[{test,do_multiply,5,2,3},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]}
** exited: {function_clause,[{test,do_multiply,5,2,3},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]} **
It is clear that the problem is in do_multiply(...)

Digg It
Del.icio.us
Reddit
Facebook
Stumble Upon
Technorati

