Option
monad is a great expressive way to deal with something-or-nothing things in Scala. But what if one needs to log a message when "nothing" occurs? According to the Scala API documentation,
The Either type is often used as an alternative to scala.Option where Left represents failure (by convention) and Right is akin to Some.
However, I had no luck to find best practices using Either or good real-world examples involving Either for processing failures. Finally I've come up with the following code for my own project:
def logs: Array[String] = { def props: Option[Map[String, Any]] = configAdmin.map{ ca => val config = ca.getConfiguration(PID, null) config.properties getOrElse immutable.Map.empty } def checkType(any: Any): Option[Array[String]] = any match { case a: Array[String] => Some(a) case _ => None } def lookup: Either[(Symbol, String), Array[String]] = for {val properties <- props.toRight('warning -> "ConfigurationAdmin service not bound").right val logsParam <- properties.get("logs").toRight('debug -> "'logs' not defined in the configuration").right val array <- checkType(logsParam).toRight('warning -> "unknown type of 'logs' confguration parameter").right} yield array lookup.fold(failure => { failure match { case ('warning, msg) => log(LogService.WARNING, msg) case ('debug, msg) => log(LogService.DEBUG, msg) case _ => }; new Array[String](0) }, success => success) }
(Please note this is a snippet from a real project, so it will not compile on its own)
I'd be grateful to know how you are using Either
in your code and/or better ideas on refactoring the above code.
In Scala Either, functions exactly similar to an Option. The only dissimilarity is that with Either it is practicable to return a string which can explicate the instructions about the error that appeared.
Like Java, Scala has a try/catch/finally construct to let you catch and manage exceptions. The main difference is that for consistency, Scala uses the same syntax that match expressions use: case statements to match the different possible exceptions that can occur.
try/catch/finally A basic way we can handle exceptions in Scala is the try/catch/finally construct, really similar to the Java one. In the following example, to make testing easier, we'll return a different negative error code for each exception caught: def tryCatch(a: Int, b: Int): Int = { try { return Calculator.
The Try type represents a computation that may either result in an exception, or return a successfully computed value. It's similar to, but semantically different from the scala. util. Either type. Instances of Try[T] , are either an instance of scala.
Either is used to return one of possible two meaningful results, unlike Option which is used to return a single meaningful result or nothing.
An easy to understand example is given below (circulated on the Scala mailing list a while back):
def throwableToLeft[T](block: => T): Either[java.lang.Throwable, T] = try { Right(block) } catch { case ex => Left(ex) }
As the function name implies, if the execution of "block" is successful, it will return "Right(<result>)". Otherwise, if a Throwable is thrown, it will return "Left(<throwable>)". Use pattern matching to process the result:
var s = "hello" throwableToLeft { s.toUpperCase } match { case Right(s) => println(s) case Left(e) => e.printStackTrace } // prints "HELLO" s = null throwableToLeft { s.toUpperCase } match { case Right(s) => println(s) case Left(e) => e.printStackTrace } // prints NullPointerException stack trace
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With