%% Used destructive assignment in the process dictionary
%% to keep count of handled exceptions.
%%
%% Usage: start from command line with
%% erlc exceptions.erl
%% erl -noinput -s exceptions main 200000
-module(except).
-export([main/1]).
blowup(N) when N rem 2 == 0 -> throw({lo_exception, N});
blowup(N) -> throw({hi_exception, N}).
lo_fun(N) ->
case catch blowup(N) of
{lo_exception, N1} -> put(lo_count, get(lo_count) + 1);
{hi_exception, N2} -> throw({hi_exception, N2})
end.
hi_fun(N) ->
case catch lo_fun(N) of
{hi_exception, N1} -> put(hi_count, get(hi_count) + 1);
_ -> true
end.
some_fun(N) when N > 0 ->
case catch hi_fun(N) of
{lo_exception, N1} -> io:fwrite("~s~n", ["lo_exception should not get here."]);
{hi_exception, N2} -> io:fwrite("~s~n", ["hi_exception should not get here."]);
_ -> true
end,
some_fun(N - 1);
some_fun(0) -> true.
main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
put(hi_count, 0),
put(lo_count, 0),
some_fun(Num),
io:fwrite("~s~w ~s~w~n", ["Exceptions: HI=", get(hi_count),"/ LO=", get(lo_count)]),
halt(0).