Scala Constructor/Method Parameter Checking - scala

I wanted to check some best practices of Scala programming, since I am new to Scala. I read online about how Scala doesn't typically use exceptions except for "exceptional" circumstances (which doesn't include parameter checking). Right now in my project I am using a lot of require, so I am wondering what the better way of type checking would be.
For example, if I have a class
class Foo(String bar){
require(StringUtils.isNotEmpty(bar), "bar can't be empty")
}
what are my alternatives to checking bar? Do I create a companion object like so
Object Foo {
def apply(bar: String) = Try[Foo] {
bar match = {
case null => Failure("can't be null")
//rest of checks
case _ => Success[Foo]
}
}
Or should I use Option instead?
In addition, for scala methods, how do I check the parameter of the method? If I already return an Option, do I just return an empty Option if I get a bad parameter? Wouldn't that mean I have to check for an empty Option when I use the return of the method and wouldn't throwing an exception allow for a more specific message? (e.g. runtime exception can't use nulls).

I think the Success part of your companion object would return the Foo() object as well?
Object Foo {
def apply(bar: String) = Try[Foo] {
bar match = {
case null => Failure("can't be null")
//rest of checks
case _ => Success[Foo](new Foo(bar))
}
}
To use it you might do something with the Success you get from Foo(bar):
val hehe = Foo(bar).map(foo => foo.someString()).getOrElse('failed')
The Try methods will automatically wrap exceptions generated by someString() or whatever else that you're doing inside it inside Failures. If you wanted to check the parameters of foo.someString(), you'd do something similar to your apply() method. It isn't that much different than throwing exceptions on conditions but I think it's nicer cause the "catch blocks" would be in recover() or recoverWith(). You can always exit the Try using getOrElse() if your code wasn't designed to chain Trys from top to bottom.

Related

Difference between Future[Any] and Future[_]

Okay, I guess question is already complete in the title.
Nothing big, but I am just wondering. I have a method which returns either a correct value or an error code enum item. For example something like this:
def doMyStuff(): Future[_] = {
val result = db.queryMyData().map {
case some(data) =>
val modifiedData = data.doStuff()
modifiedData
case None =>
Errors.THIS_IS_FALSE
}
result
}
Where db.queryMyData() returns a Future, and data.doStuff() just modifies the data.
Now I have intuitively written Future[_], cause the return value is flexible. But when looking in other libraries I've seen Future[Any] used. Which seems to be logic too, when you use a match-case on the return of the function to check which data it is.
The code which uses that is for example something like this:
doMyStuff().map {
case data: MyDataType => // Blah blah
case Errors.Value => // error handling
}
So, my questions is: What's the difference between the use of Any or _ here, and why should I use the correct one?
It is a matter of semantics:
The Existential TypeT[_] means there is a class/type at the position of _ for which I do not care at all but it must be there.
T[Any] means there has to be a subclass Any present.
The difference comes into play when you want to serialize the underlying class.
If you just use _ without any typebounds you will not be able to use some of the many Scala JSON libraries.

Scala: How to return a Some or Option

I have the following piece of code that I am trying to enhance:
I am using the java.nio.file package to represent a directory or a file as a Path.
So here goes:
import java.nio.file.{Paths,DirectoryStream,Files,
Path,DirectoryIteratorException}
val path: Path = Paths.get(directoryPath)
var directoryStream: Option[DirectoryStream[Path]] = None
// so far so good
try {
directoryStream = Some(Files.newDirectoryStream(pathO))
// this is where i get into trouble
def getMeDirStream: DirectoryStream[Path] =
if (!directoryStream.isEmpty && directoryStream.isDefined)
getMeDirStream.get
else
None
// invoke the iterator() method of dstream here
}
The above piece of code will not compile because I do not know what to return in the else, and right now, for the life of me, I can only come up with None, which the compiler simply does not like and I would like to learn what should be its replacement.
I want this example to be a learning lesson of Option and Some for me.
Okay, this is where I choke. I would like to check if the directoryStream is not empty and is defined, and then if this is the case, I would like to invoke getMeDirStream.get to invoke the iterator() method on it.
The API for Option tells me that invoking the get() method could result in a java.util.NoSuchElementException if the option is empty.
If the directoryStream is empty I want to return something and not None, because IntelliJ is telling me that "Expression of type None.type doesn't conform to expected type DirectoryStream[Path]".
Now, I am being all naive about this.
I would like to know the following:
What should I return in the else other than None?
Should I wrap the getMeDirStream.get in a try-catch with a java.util.NoSuchElementException, even though I am checking if the directoryStream is empty or not.?
What is the purpose of a try-catch in the getMeDirStream.get, if there is indeed such a need?
How can I clean up the above piece of code to incorporate correct checks for being isDefined and for catching appropriate exceptions?
Once I know what to return in the else (and after putting in the appropriate try-catch block if necessary), I would like to invoke the iterator() method on getMeDirStream to do some downstream operations.
Some and None are subtypes of Option, but to be more correct, they are actually two different cases of Option or data constructors. In other words, even though Scala allows you to directly invoke a Some or a None you should still regard their type to be Option. The more important thing to take from this is that you should never under any circumstance invoke Option#get as it is unsafe.
The intention of Option is to indicate the possibility that a value does not exist. If you care about the errors, then you should probably look at using Either instead (or Scalaz's Either called \/).
You can keep the computation within the Option context and then only extract the value later, or provide a default.
def fromTryCatch[A](a: => A): Either[Throwable, A] = try { Right(a) } catch { case e: Throwable => Left(e) }
val getMeDirStream: Option[java.util.Iterator[Path]] =
for {
path <- fromTryCatch(Paths.get(directoryPath)).toOption
directoryStream <- fromTryCatch(Files.newDirectoryStream(pathO)).toOption
} yield directoryStream.iterator()
Later, or right after, you can get the iterator, or provide a default value:
val iterator = getMeDirStream.getOrElse(java.util.Collections.emptyIterator[Path])
Your specific questions are difficult to address because it's unclear exactly what you're trying to achieve. In particular, when you ask what the purpose of the try block is... Well, you wrote it, so only you can answer that.
In general, you never call get on an Option. You either use pattern matching:
option match {
case Some(value) => /* ... */
case None => /* ... */
}
or you use methods like map, flatMap, and foreach (or the equivalent comprehension syntax that gpampara's code uses).
My revision of gpampara's answer:
import scala.collection.convert.wrapAll._
import scala.util.Try
import java.nio.file.{Paths, Files, Path}
val getMeDirStream: Option[Iterator[Path]] =
for {
path <- Try(Paths.get("")).toOption
directoryStream <- Try(Files.newDirectoryStream(path)).toOption
} yield directoryStream.iterator
Changes:
Using Try(...).toOption instead of Either
Using implicits in scala.collection.convert to return the result as a Scala Iterator.
Try is similar to Option. Instead of Some and None, it has Success and Failure subtypes, and the failure case includes a Throwable, whereas None is just a singleton with no additional information.

Fusing execution flow and exception flow in Scala

I am using the following to wrap a Boolean function and return its success status:
def wrapper(wrapped: => Boolean) : Boolean = { // this form of prototype takes a function by name
try {
return wrapped
} catch {
case anyException : Throwable =>
log(anyException.toString)
return false }
}
The rationale being that the wrapper function should return an overall binary status, regardless of whether the wrapped function failed to capture its own unexpected exceptions and do the same. So the wrapper conveys success and failure via its Boolean return value. It can also be an Option for function result data, rather than a Boolean.
How would you accomplish this in other, even better ways, in Scala?
I note that one rationale (of few others) for this code, admittedly has been that try catch blocks are cumbersome in flow control blocks. Another has been that I tend to use this pattern a lot in a certain area of my project.
You can use Try. Although it will catch only NonFata(scala.util.control.NonFatal) but in most cases this is what you do want.
import scala.util.Try
def wrapper(predicate: => Boolean) : Boolean = {
Try(predicate) getOrElse false
}
Or another way (For example if you really do want to catch any Throwable)
import scala.util.control.Exception._
def wrapper(predicate: => Boolean) : Boolean = {
catching(classOf[Throwable]) opt predicate getOrElse false
}
Scala provides Try feature, which is intended to be used in this occasions.
Notice that keeping your current wrapper leads to potential several errors. When you get a false result, you cannot know if it came from an application exception or a simple false evaluation. Thus, you can't properly handle any exception in your system, which may lead to multiple inconsistencies. Moreover, when you get a false result, your application internal state could be considered as unknown, making it very difficut to look into the box to know if the cat is dead or alive.
To solve this, scala's Try feature will handle this possible states for you, returning -in your case- a Success(elem: Boolean) in case your predicate effectively executes, and a Failure(ex: Throwable) in case an exception was thrown during execution. Then, you can use pattern matching to find out which was the case:
import scala.util.{Try, Success, Failure}
[...]
Try(predicate) match {
case Success(bool) => bool
case Failure(ex) => /* Do something to handle ex */
}
This somehow eliminates the need of your wrapper, for you can keep Try's result and then either match it or get it's result whenever you need to. And, as seen in previous answers, there is a rather complete set of operations you can use to handle all this cases in a more fashionable way.

Making code more scala idiomatic

I came across following java like code in Scala project. how to make it more Scala idiomatic with no side effects (exception handling appropriately) ?
I am thinking to use scalaz disjunction / (I know I can use Scala either too but like right biased more I guess). in a function there are a few such if checks(one above is one example) which throw one or the other type of exceptions. how to make such code more Scala idiomatic?
EDIT:
Question is not around how to convert Java null checks into Scala Idiomatic, which I am already doing. for e.g. following
hpi.fold(throw new Exception("Instance not found for id " + processInstanceId)) { h =>
val pi = new ProcessInstance(taskResponse)
Now return type of the existing function is some value say "ProcessInstance" for e.g. but in my opinion is misleading. caller would never know if this will throw an exception so my question is more around returning Either[Error,Value] from such functions. And if I have a few such exceptions being captured into a single function, how to accumulate them all and reflect into return type?
One thought might making processDefinition.getDiagramResourceName() return an Option, so you can then check whether the result is Some(x) or None.
Using scalaz and being idiomatic this is probably what I would end up with (subject to refactoring):
for {
pd <- Option(processDefinition.getDiagramResourceName()).\/>("Diagram resource could not be found")
} yield pd
So if you have null you get back Left("Diagram resource could not be found") otherwise you get Right(DiagramResourceName).
An approach based in case classes where different subclasses of names, references or labels may be defined,
trait ResourceName
case object MissingName extends ResourceName
case class DiagramResourceName(name: String) extends ResourceName
case class AnotherResourceName(ref: Int) extends ResourceName
processDefinition.getDiagramResourceName() match {
case DiagramResourceName(name) => println(s"name $name")
case MissingName => throw new ActivityException(errorMessage)
}

What are the use cases for Scala 2.9's try...catch generalization?

I've read about and experimented with the Scala 2.9 try...catch feature, and it has me thinking about possibilities. What would I actually use it for other than saving a couple of lines of code?
Scala 2.9 Final Release Notes
The use case is to be able to have generic error handling throughout your application. Let's say you want to handle all FileNotFoundExceptions in your application by sending an e-mail to an administrator. Previously, you'd have to do it like this:
// Globally
val fileNotFound: PartialFunction[Throwable, Unit] = {
case e: FileNotFoundException =>
// Create report and send the e-mail
}
// On each try-catch-block
try {
// Open file
}
catch {
case fnf: FileNotFoundException => fileNotFound(fnf)
}
Now you just do:
try {
// Open file
} catch fileNotFound
This also has the nice advantage that you can link several such exception handlers using the orElse method on partial functions:
val fileErrors = fileNotFound orElse endOfFile orElse invalidFormat
And then just use that everywhere where you need file exception handling. Such an error handler can be dynamically combined based on the configuration file for the application, for example. This is much less cumbersome than pattern matching everywhere and calling the correct handler.
One useful thing which could be pimped on top of partial functions is the andAlso operator, which acts as a sequencing operator on two partial functions. This would be useful when you want to do some error handling specific to a particular try-catch block after having done the generic error handling.
implicit def pf2ops(pf: PartialFunction[Throwable, Unit]) = new {
def andAlso(localpf: PartialFunction[Throwable, Unit]) = new PartialFunction[Throwable, Unit] {
def apply(t: Throwable) = {
if (pf.isDefinedAt(t)) pf(t)
localpf(t)
}
def isDefinedAt(t: Throwable) = pf.isDefinedAt(t) || localpf.isDefinedAt(t)
}
}
And then you can do this:
scala> try {
| throw new java.io.FileNotFoundException
| } catch fnf andAlso {
| case e: Exception => println("I don't know, but something is specific to this particular block.")
| }
I don't know, but something is specific to this particular block.
I guess you could play further with the exact semantics and the meaning (and the name) of andAlso.
Good answer by axel22, but I think the real reason for its introduction is something else. The try/catch/finally handling introduced a special case. You used a partial function literal, but you could not actually replace that with a partial function. Now, catch just receive a partial function, and one more special case in the language is gone.