Created
September 13, 2012 19:06
-
-
Save eboto/3716806 to your computer and use it in GitHub Desktop.
Authentication: Nested match vs For Comprehension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Let's authenticate an attempted email and password against our database in two different ways | |
* using scala. Authentication can fail due to: | |
* (1) No account matching the e-mail (findByEmail(someEmail) can be either None or Some(Account)) | |
* (2) No password being associated with the account (account.password can be either None | |
* or Some(Password)) | |
* (3) The password for the account was incorrect (password.is(attempt) returns true or false) | |
* | |
* We'll take two different approaches: one using a series of pattern matches and another using | |
* for comprehensions. Which is more readable? Which is more idiomatic? <gruff military voice> I'm | |
* afraid the answer to that question is above my pay grade. </gruff military voice> | |
*/ | |
/* | |
* Authenticate via nested pattern matches | |
*/ | |
def authenticate(email: String, passwordAttempt: String): Either[AccountAuthenticationError, Account] = { | |
import AccountAuthenticationError._ | |
findByEmail(email) match { | |
case None => | |
Left(new AccountNotFoundError) | |
case Some(account) => | |
account.password match { | |
case None => | |
Left(new AccountPasswordNotSetError) | |
case Some(password) if password.is(passwordAttempt) => | |
Right(account) | |
case _ => | |
Left(new AccountCredentialsError) | |
} | |
} | |
} | |
/* | |
* Authenticate via for-comprehension | |
*/ | |
def authenticate(email: String, passwordAttempt: String): Either[AccountAuthenticationError, Account] = { | |
import AccountAuthenticationError._ | |
for ( | |
account <- findByEmail(email).toRight(left=new AccountNotFoundError).right; | |
password <- account.password.toRight(left=new AccountPasswordNotSetError).right; | |
verifiedAccount <- { | |
val badCredentialsOrAccount = if (password.is(passwordAttempt)) { | |
Right(account) | |
} else { | |
Left(new AccountCredentialsError) | |
} | |
badCredentialsOrAccount.right | |
} | |
) yield { | |
verifiedAccount | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think that for comprehensions are cool, and I think I wanted to say the for-comprehension was easier to understand when I read the top.
But if I really think that in this example, nested case is totally easier to understand. I'm not certain if the example got more complicated that I would feel the same.