Using Option all over the place feels a bit awkward. Am I doing something wrong?

scala, scala-option

Solution

It's generally not a good idea to return `Option` and then use `getOrElse` to produce some sentinel value that means "not found". That's what `Option` is designed for: to signify that a value is not found!

`Option` really shows its power when used in conjunction with functional programming constructs like `map` and `foreach`. This is most potent when dealing with multiple options. For example, suppose I write a method that takes a string and gives me back a file, but only if the file exists and is a file not a directory:

import java.io._;
def niceFile1(s: String): File = {
  val f = new File(s);
  if (f.exists && !f.isDirectory) f else null
}
def niceFile2(s: String): Option[File] = {
  val f = new File(s);
  if (f.exists && !f.isDirectory) Some(f) else None
}

So far, using `null` is easier--at least until you forget that this might give you `null` and you get a NPE. Anyway, let's now try to use it.

def niceFopen1(s: String) = {
  val f = niceFile1(s);
  if (f!=null) new FileInputStream(f) else null;
}
def niceFopen2(s: String) = niceFile2(s).map(f => new FileInputStream(f))

Look what happened! In the former case, we had to do logic tests by hand and create temporary variables. Ugh! In the second case, `map` did all the dirty work for us: None was mapped to None, and `Some(file)` was mapped to `Some(fileinputstream)`. Easy!

But it gets better yet. Maybe we want to find the size of a whole bunch of files:

def totalSize2(ss: Seq[String]) = {
  (0L /: ss.flatMap(niceFile2)){(sum,f) => sum+f.length}
}

Wait, what is going on here--what about all the `None`? Don't we have to pay attention and handle them somehow? Well, that's where `flatMap` comes in: it joins together all the answers into a single list. `None` is an answer of length zero, so it ignores it. `Some(f)` has one answer--`f`--so it puts it in the list. Then we use a fold to add up all the lengths--now that all the elements in the list are valid. Pretty nice!

Problem

As a result of articles I read about the `Option` class which helps you avoid NullPointerException's, I started to use it all over the place. Imagine something like this: ``` var file:Option[File] = None ``` and later when I use it: ``` val actualFile = file.getOrElse(new File("nonexisting")) if(actualFile.getName.equals("nonexisting")) { // instead of null checking } else { // value of file was good } ``` Doing stuff like this doesn't feel all that "right" to me. I also noticed that `.get` has become deprecated. . Is this sort of stuff what you guys are doing with Option's too, or am I going the wrong way?

Original source