[erlang-questions] How do I elegantly check many conditions?
Jachym Holecek
freza@REDACTED
Fri Mar 20 15:30:32 CET 2009
Hello,
# ryeguy 2009-03-20:
> So when a user sends a request to register an account, they send their
> username, password, email, and other info. The registration function
> must verify all of their data. An example would be:
BTW observe that your tests are of two different kinds:
> - verify username is alphanumeric
> - verify all fields are above X characters long
> - verify all fields are less than Y characters long
These check the shape of incoming data, that is they decide if the
incoming request makes any sense at all.
> - verify email not in use
> - verify username not in use
These have a valid request at hand and decide if the system is
able to fulfill it given current state of the world.
It seems like a good idea to keep the two separate in some way. It might
also make some amount of sense to merge the second kind of check with the
actual registration procedure.
> Now I don't want to have a 5 level deep if or case statement, but what
> other options do I have? Splitting it into separate functions sounds
> like a good idea, but then I just have to check the return value of
> the functions in some sort of conditional and it's back to the
> original problem.
I can't see the problem of using nested 'case' expressions, as long
as the resulting code is clear and simple.
> I could separate them into functions and then call an if statement
> with all of the conditionals OR'd together, but that wouldn't give me
> what I want because I need to be able to tell the user the specific
> error if there was one.
>
> How does one handle this kind of situation in erlang?
I'd probably go with something like the below. But in general, I find
writing partial solutions an extremely confusing task. So, depending
on how the rest of your code works, I might actually go with something
completely different. ;-)
HTH,
-- Jachym
%% Handle user registration request.
request(Username, Password, Email) ->
case lists:all(fun in_bounds/1, [Username, Password, Email]) of
true ->
case is_alpha(Username) of
true ->
add_user(Username, Password, Email);
false ->
error
end;
false ->
error
end.
%% Add new user unless his details conflict with existing user. Return 'ok' on success, 'error' on collision.
add_user(Username, Password, Email) ->
%% XXX If you store users in Mnesia, you'd probably want to write
%% XXX a check-and-insert function and run that as transaction
%% XXX instead. It would return a boolean indicating success. If
%% XXX you're not using Mnesia, you need to deal with the obvious
%% XXX race condition lurking here yourself :-).
case is_available(Username, Email) of
true ->
whatever_it_takes_to_add_user(Username, Password, Email),
ok;
false ->
error
end.
%% Decide if string has acceptable length.
in_bounds(String) when length(String) > 3, length(String) < 10 ->
true;
in_bounds(_) ->
false.
%% Decide if string is composed of alphanumeric characters.
is_alpha([Char | Rest]) when Char >= $a, Char =< $z ->
is_alpha(Rest);
is_alpha([Char | Rest]) when Char >= $A, Char =< $Z ->
is_alpha(Rest);
is_alpha([Char | Rest]) when Char >= $0, Char =< $9 ->
is_alpha(Rest);
is_alpha([]) ->
true;
is_alpha(_) ->
false.
More information about the erlang-questions
mailing list