[erlang-questions] How do I elegantly check many conditions?

ryeguy <>
Mon Mar 23 15:17:50 CET 2009


Here is how I ended up doing it. I am mostly satisfied with it.

register(#packet{data=[Username, Password, Email]}) ->
	User=#user{id         = {node(), now()},
			   username   = Username,
			   password   = Password,
			   email      = Email,
			   reg_date   = erlang:localtime()},
	try
		ok=validate_username(Username),
		ok=validate_email(Email),
		ok=validate_password(Password),

		{atomic, _}=mnesia:transaction(fun() ->
			%check if username and email are unique
			{username, []}={username, mnesia:index_read(user, Username,
#user.username)},
			{email, []}={email, mnesia:index_read(user, Email, #user.email)},
			mnesia:write(User)
		end),
		ok
	catch
		error:{badmatch,{password, false}} -> {error, ?E_PASSWORD_FORMAT};
		error:{badmatch,{username, _, _}} -> {error, ?E_USRNAME_FORMAT};
		error:{badmatch,{email, _, _, _}} -> {error, ?E_EMAIL_FORMAT};
		error:{badmatch,{email, false}} -> {error, ?E_EMAIL_FORMAT};

		error:{badmatch, {aborted, {{badmatch, {username, _}}, _}}} ->
{error, ?E_USRNAME_IN_USE};
		error:{badmatch, {aborted, {{badmatch, {email, _}}, _}}} -> {error, ?
E_EMAIL_IN_USE}
	end.

The only thing I kinda dislike is the badmatch catching for possible
errors inside of the mnesia transaction. They're just sloppy looking.
I know that I could use if or cases with mnesia:abort, but that would
just further nest my transaction, give it more code, and be
inconsistent with the pre-transaction checking (since I use pattern
matching there, and I'd be using if/case in the transaction).

Any suggestions at all? Or is this fine?

On Mar 21, 1:37 am, Geoff Cant <> wrote:
> ryeguy <> writes:
> > 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:
>
> >  - verify email not in use
> >  - verify username not in use
> >  - verify username is alphanumeric
> >  - verify all fields are above X characters long
> >  - verify all fields are less than Y characters long
>
> > 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 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 ran into this when building a website recently and ended up building a
> form validation
> library. (http://github.com/archaelus/ejango/tree/master- the form
> validation checking engine is located here,http://github.com/archaelus/ejango/blob/1d76e5c230e99725b815d258e889d...)
> You can see examples of almost all the validation rules you gave above
> in the unit tests for the form_validator module. There's some
> documentation on how to specify them around line 109 in the
> form_validator file.
>
> I was trying to create a DSL for declaratively specifying forms and the
> rules for validating particular fields. E.g. {"user_email",
> [email_address, not_empty, {predicate, fun
> yourcode:check_email_in_use/1}]} Checks that the value of the form field
> "user_email" is not the empty string, matches the regex for email
> address validation and calling yourcode:check_email_in_use(<value of the
> "user_email" field>) returns true. The validation engine will report
> errors for each rule given for a field so that you can give meaningul
> error messages such as "Email address in use" and localise them if
> necessary.
>
> The library has patchy edoc and some eunit test coverage - the validator
> itself has edoc, but unfortunately the high level declarative form API
> isn't documented well yet. It's on my todo list, but if someone beats me
> to it I'd be happy to apply any patches. The library works well
> enough that it has been used in a website I'm about to unveil soon.
>
> Cheers,
> --
> Geoff Cant
>
> _______________________________________________
> erlang-questions mailing list
> ://www.erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list