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.

Line 82:

Line 87:

It is clear that the problem is in do_multiply(...)

It is clear that the problem is in do_multiply(...)

+

+

+

== Better Solution: ==

+

+

+

1: -module(test).

+

2: -export([function/2]).

+

3: function(Oper,Val)->

+

4: case {oper,Oper} of

+

5: {oper,null}->

+

6: null;

+

7: {oper,multiply}->

+

8: case {val,Val} of

+

9: {val,[A,B]} when integer(A), integer(B)

+

10: -> {ok,A*B}

+

11: end

+

12: end.

+

+

+

1: 4> test:function(multiply,[5,2]).

+

2: {ok,10}

+

3: 5> test:function(divide,[5,2]).

+

4: ** exception error: no case clause matching {oper,divide}

+

5: in function test:function/2

+

6: 6> test:function(multiply,[5,2,3]).

+

7: ** exception error: no case clause matching {val,[5,2,3]}

+

8: in function test:function/2

+

+

We've got much more clarity here as we KNOW where to find the atoms 'val' and 'oper'. We could use the atoms 'case1' and 'case2' if we would like to see which case caused the error explicitly. (Handling null cases is defensive)

We've got much more clarity here as we KNOW where to find the atoms 'val' and 'oper'. We could use the atoms 'case1' and 'case2' if we would like to see which case caused the error explicitly. (Handling null cases is defensive)