How to use Box with Java null values - scala

I use a Java method that returns an object or null if a value was not found. So I need to check for null values:
val value = javaobject.findThing(xyz)
if(value != null) {
value.doAnotherThing()
} else {
warn("Value not found.")
}
Can I write this code shorter with the Box concept? I have read the Lift-Wiki-documentation about the Box concept, but I don't understand how to use it with Java null values.

#TimN is right, you could use Box(value) to create a Box from a possibly null value, but you'll get a deprecation warning.
scala> val v: Thing = null
v: Thing = null
scala> Box[Thing](v)
<console>:25: warning: method apply in trait BoxTrait is deprecated: Use legacyNullTest
Box[Thing](v)
While you could use Box.legacyNullTest, if this is what you're doing, then I would just stick with the standard library and use Option.
Option(javaobject.findThing(xyz)) match {
case Some(thing) => thing.doAnotherThing()
case _ => warn("Value not found.")
}
And if you needed a Box to pass around, Option will automagically convert to a Box:
scala> val b: Box[Thing] = Option(v)
b: net.liftweb.common.Box[Thing] = Empty

Similar to Scala's Option, you can simply call Box() and pass in the value that may or may not be null, and you'll get a Box object that can be used normally. For example:
Box(javaobject.findThing(xyz)) match {
case Full(thing) => thing.doAnotherThing()
case _ => warn("Value not found.")
}

You can use Box.legacyNullTest. This method encapsulates any object in a Box in a null-safe manner:
def legacyNullTest[T](in: T): Box[T] = in match {
case null => Empty
case _ => Full(in)
}
Box returned from legacyNullTest can be later used as usual in for comprehensions or in pattern matching:
for {
fragment <- Box.legacyNullTest(uri.getFragment)
yield {
doSth(fragment)
}
or
Box.legacyNullTest(uri.getFragment) match {
case Full(fragment) =>
doSth(fragment)
case _ =>
log.error("Missing fragment part")
doSthElse
}

Related

scala: updating string value in an option

I have an Option of a string. I want to update the contained value:
if(x.isEmpty) {
...another calculation
} else {
x.map(val => ...update val)
}
Is this an idiomatic way?
x.fold(another calculation)(v => ...update v)
e.g.
x.fold("no value")("Value is " + _)
Note that this extracts the value from the Option so if you want to have the result as an Option you need to wrap it in Some.
Note that if your inner computation gets too long or unreadable for a fold, there's always good old-fashioned pattern matching.
x match {
case None => {
// None case ...
}
case Some(y) => {
// Some case (y is the inside) ...
}
}
Like everything in Scala, this is an expression, so it can be assigned to a variable or used in another other expression you like.
Alternatively, using the lazy keyword:
// T is the type of the value
val valueOpt: Option[T] = ???
lazy val backupValue: T = ??? // Other calculation, but only evaluated if needed
val value: T = valueOpt.map( v => /*Update v*/ ).getOrElse( backupValue )
// do something with the value you want to manipulate

Option[Int] as index in loop

I am new at Scala so I do not know if I will ask something obvious.
I am currently trying to define a function which can or can not receive a parameter called "position". This parameter is an Int (in case the user decides to pass it). Otherwise, it should be considered as a "None" (because it will mean that nothing has been passed as parameter).
If it is a None, then: position = series.length - 1. I am trying to use Option here, since I do not want the user to pass a position if he does not require it.
def example(series: Vector[Double], position: Option[Int]): Vector[Double] = {
position match {
case Some(value) => value
case None => series.length - 1
}
for (i <- position until series.length) {
...
}
}
But when I try to use it in an loop as an Integer, it gives me an error (Type mismatch. Requiered: CanBuildFrom[Nothing, Int, NotInferedCol[Int]]. Found: Int).
I have been trying different things to make this "position" as an optional value, but I can't figure it out.
The issue in your code is that this:
position match {
case Some(value) => value
case None => series.length - 1
}
is an expression that doesn't mutate the value of position, which is probably what you may have assumed.
You have to bind the value produced by the expression to use it in the code underneath it:
val positionWithDefault =
position match {
case Some(value) => value
case None => series.length - 1
}
for (i <- positionWithDefault until series.length) {
...
}
Furthermore, as noted in a comment, the behavior of the match expression is the same you'd get out of getOrElse
for (i <- position.getOrElse(series.length - 1) until series.length) {
...
}

How to check for None when returning data

I am fetching my data like this
case class MyClass(s: Option[Safe] = None, t: Option[Threat] = None)
val myCheck = for {
t <- fT
s <- fS
} yield MyClass(s, t)
onComplete(myCheck) {
case Success(check) =>
check match {
case (maybeMyClass) =>
complete(ToResponseMarshallable(maybeMyClass))
}
This works well when my records are found, however, when no records are found I get a MyClass(None, None). I would like to catch that using pattern matting and throw an appropriate message. How can I use pattern matching here to catch when the data is null?
If you are dealing with values that might be null it is important to wrap them using Option. The Option object will check for null values and return None.
However, using Some will not check for null and you can get Some(null).
If you have an option that might be Some(null) you can clean it up by wrapping it in Option again by using flatMap(Option(_))
For example:
val s: String = "x"
val n: String = null
Option(s) // Some("x")
Option(n) // None
Some(s) // Some("x")
Some(n) // Some(null) <- NB
Some(n).flatMap(Option(_)) // None
Update after comments
From the comments it appears that the null is actually in JSON, and is presumably coming from parsing None rather than a Scala null. In that case you can just check for None as usual:
check match {
case MyClass(None, _) =>
// Error: missing Safe value
case MyClass(_, None) =>
// Error: missing Threat value
case _ =>
complete(ToResponseMarshallable(check))
}

Cleanest way in Scala to avoid nested ifs when transforming collections and checking for error conditions in each step

I have some code for validating ip addresses that looks like the following:
sealed abstract class Result
case object Valid extends Result
case class Malformatted(val invalid: Iterable[IpConfig]) extends Result
case class Duplicates(val dups: Iterable[Inet4Address]) extends Result
case class Unavailable(val taken: Iterable[Inet4Address]) extends Result
def result(ipConfigs: Iterable[IpConfig]): Result = {
val invalidIpConfigs: Iterable[IpConfig] =
ipConfigs.filterNot(ipConfig => {
(isValidIpv4(ipConfig.address)
&& isValidIpv4(ipConfig.gateway))
})
if (!invalidIpConfigs.isEmpty) {
Malformatted(invalidIpConfigs)
} else {
val ipv4it: Iterable[Inet4Address] = ipConfigs.map { ipConfig =>
InetAddress.getByName(ipConfig.address).asInstanceOf[Inet4Address]
}
val dups = ipv4it.groupBy(identity).filter(_._2.size != 1).keys
if (!dups.isEmpty) {
Duplicates(dups)
} else {
val ipAvailability: Map[Inet4Address, Boolean] =
ipv4it.map(ip => (ip, isIpAvailable(ip)))
val taken: Iterable[Inet4Address] = ipAvailability.filter(!_._2).keys
if (!taken.isEmpty) {
Unavailable(taken)
} else {
Valid
}
}
}
}
I don't like the nested ifs because it makes the code less readable. Is there a nice way to linearize this code? In java, I might use return statements, but this is discouraged in scala.
I personally advocate using a match everywhere you can, as it in my opinion usually makes code very readable
def result(ipConfigs: Iterable[IpConfig]): Result =
ipConfigs.filterNot(ipc => isValidIpv4(ipc.address) && isValidIpv4(ipc.gateway)) match {
case Nil =>
val ipv4it = ipConfigs.map { ipc =>
InetAddress.getByName(ipc.address).asInstanceOf[Inet4Address]
}
ipv4it.groupBy(identity).filter(_._2.size != 1).keys match {
case Nil =>
val taken = ipv4it.map(ip => (ip, isIpAvailable(ip))).filter(!_._2).keys
if (taken.nonEmpty) Unavailable(taken) else Valid
case dups => Duplicates(dups)
}
case invalid => Malformatted(invalid)
}
Note that I've chosen to match on the else part first, since you generally go from specific to generic in matches, since Nil is a subclass of Iterable I put that as the first case, eliminating the need for an i if i.nonEmpty in the other case, since it would be a given if it didn't match Nil
Also a thing to note here, all your vals don't need the type explicitly defined, it significantly declutters the code if you write something like
val ipAvailability: Map[Inet4Address, Boolean] =
ipv4it.map(ip => (ip, isIpAvailable(ip)))
as simply
val ipAvailability = ipv4it.map(ip => (ip, isIpAvailable(ip)))
I've also taken the liberty of removing many one-off variables I didn't find remotely necessary, as all they did was add more lines to the code
A thing to note here about using match over nested ifs, is that is that it's easier to add a new case than it is to add a new else if 99% of the time, thereby making it more modular, and modularity is always a good thing.
Alternatively, as suggested by Nathaniel Ford, you can break it up into several smaller methods, in which case the above code would look like so:
def result(ipConfigs: Iterable[IpConfig]): Result =
ipConfigs.filterNot(ipc => isValidIpv4(ipc.address) && isValidIpv4(ipc.gateway)) match {
case Nil => wellFormatted(ipConfigs)
case i => Malformatted(i)
}
def wellFormatted(ipConfigs: Iterable[IpConfig]): Result = {
val ipv4it = ipConfigs.map(ipc => InetAddress.getByName(ipc.address).asInstanceOf[Inet4Address])
ipv4it.groupBy(identity).filter(_._2.size != 1).keys match {
case Nil => noDuplicates(ipv4it)
case dups => Duplicates(dups)
}
}
def noDuplicates(ipv4it: Iterable[IpConfig]): Result =
ipv4it.map(ip => (ip, isIpAvailable(ip))).filter(!_._2).keys match {
case Nil => Valid
case taken => Unavailable(taken)
}
This has the benefit of splitting it up into smaller more manageable chunks, while keeping to the FP ideal of having functions that only do one thing, but do that one thing well, rather than having god-methods that do everything.
Which style you prefer, of course is up to you.
This has some time now but I will add my 2 cents. The proper way to handle this is with Either. You can create a method like:
def checkErrors[T](errorList: Iterable[T], onError: Result) : Either[Result, Unit] = if(errorList.isEmpty) Right() else Left(onError)
so you can use for comprehension syntax
val invalidIpConfigs = getFormatErrors(ipConfigs)
val result = for {
_ <- checkErrors(invalidIpConfigs, Malformatted(invalidIpConfigs))
dups = getDuplicates(ipConfigs)
_ <- checkErrors(dups, Duplicates(dups))
taken = getAvailability(ipConfigs)
_ <- checkErrors(taken, Unavailable(taken))
} yield Valid
If you don't want to return an Either use
result.fold(l => l, r => r)
In case of the check methods uses Futures (could be the case for getAvailability, for example), you can use cats library to be able of use it in a clean way: https://typelevel.org/cats/datatypes/eithert.html
I think it's pretty readable and I wouldn't try to improve it from there, except that !isEmpty equals to nonEmpty.

How to check for null or false in Scala concisely?

In Groovy language, it is very simple to check for null or false like:
groovy code:
def some = getSomething()
if(some) {
// do something with some as it is not null or emtpy
}
In Groovy if some is null or is empty string or is zero number etc. will evaluate to false. What is similar concise method of testing for null or false in Scala?
What is the simple answer to this part of the question assuming some is simply of Java type String?
Also another even better method in groovy is:
def str = some?.toString()
which means if some is not null then the toString method on some would be invoked instead of throwing NPE in case some was null. What is similar in Scala?
What you may be missing is that a function like getSomething in Scala probably wouldn't return null, empty string or zero number. A function that might return a meaningful value or might not would have as its return an Option - it would return Some(meaningfulvalue) or None.
You can then check for this and handle the meaningful value with something like
val some = getSomething()
some match {
case Some(theValue) => doSomethingWith(theValue)
case None => println("Whoops, didn't get anything useful back")
}
So instead of trying to encode the "failure" value in the return value, Scala has specific support for the common "return something meaningful or indicate failure" case.
Having said that, Scala's interoperable with Java, and Java returns nulls from functions all the time. If getSomething is a Java function that returns null, there's a factory object that will make Some or None out of the returned value.
So
val some = Option(getSomething())
some match {
case Some(theValue) => doSomethingWith(theValue)
case None => println("Whoops, didn't get anything useful back")
}
... which is pretty simple, I claim, and won't go NPE on you.
The other answers are doing interesting and idiomatic things, but that may be more than you need right now.
Well, Boolean cannot be null, unless passed as a type parameter. The way to handle null is to convert it into an Option, and then use all the Option stuff. For example:
Option(some) foreach { s => println(s) }
Option(some) getOrElse defaultValue
Since Scala is statically type, a thing can't be "a null or is empty string or is zero number etc". You might pass an Any which can be any of those things, but then you'd have to match on each type to be able to do anything useful with it anyway. If you find yourself in this situation, you most likely are not doing idiomatic Scala.
In Scala, the expressions you described mean that a method called ? is invoked on an object called some. Regularly, objects don't have a method called ?. You can create your own implicit conversion to an object with a ? method which checks for nullness.
implicit def conversion(x: AnyRef) = new {
def ? = x ne null
}
The above will, in essence, convert any object on which you call the method ? into the expression on the right hand side of the method conversion (which does have the ? method). For example, if you do this:
"".?
the compiler will detect that a String object has no ? method, and rewrite it into:
conversion("").?
Illustrated in an interpreter (note that you can omit . when calling methods on objects):
scala> implicit def any2hm(x: AnyRef) = new {
| def ? = x ne null
| }
any2hm: (x: AnyRef)java.lang.Object{def ?: Boolean}
scala> val x: String = "!!"
x: String = "!!"
scala> x ?
res0: Boolean = true
scala> val y: String = null
y: String = null
scala> y ?
res1: Boolean = false
So you could write:
if (some ?) {
// ...
}
Or you could create an implicit conversion into an object with a ? method which invokes the specified method on the object if the argument is not null - do this:
scala> implicit def any2hm[T <: AnyRef](x: T) = new {
| def ?(f: T => Unit) = if (x ne null) f(x)
| }
any2hm: [T <: AnyRef](x: T)java.lang.Object{def ?(f: (T) => Unit): Unit}
scala> x ? { println }
!!
scala> y ? { println }
so that you could then write:
some ? { _.toString }
Building (recursively) on soc's answer, you can pattern match on x in the examples above to refine what ? does depending on the type of x. :D
If you use extempore's null-safe coalescing operator, then you could write your str example as
val str = ?:(some)(_.toString)()
It also allows you to chain without worrying about nulls (thus "coalescing"):
val c = ?:(some)(_.toString)(_.length)()
Of course, this answer only addresses the second part of your question.
You could write some wrapper yourself or use an Option type.
I really wouldn't check for null though. If there is a null somewhere, you should fix it and not build checks around it.
Building on top of axel22's answer:
implicit def any2hm(x: Any) = new {
def ? = x match {
case null => false
case false => false
case 0 => false
case s: String if s.isEmpty => false
case _ => true
}
}
Edit: This seems to either crash the compiler or doesn't work. I'll investigate.
What you ask for is something in the line of Safe Navigation Operator (?.) of Groovy, andand gem of Ruby, or accessor variant of the existential operator (?.) of CoffeeScript. For such cases, I generally use ? method of my RichOption[T], which is defined as follows
class RichOption[T](option: Option[T]) {
def ?[V](f: T => Option[V]): Option[V] = option match {
case Some(v) => f(v)
case _ => None
}
}
implicit def option2RichOption[T](option: Option[T]): RichOption[T] =
new RichOption[T](option)
and used as follows
scala> val xs = None
xs: None.type = None
scala> xs.?(_ => Option("gotcha"))
res1: Option[java.lang.String] = None
scala> val ys = Some(1)
ys: Some[Int] = Some(1)
scala> ys.?(x => Some(x * 2))
res2: Option[Int] = Some(2)
Using pattern matching as suggested in a couple of answers here is a nice approach:
val some = Option(getSomething())
some match {
case Some(theValue) => doSomethingWith(theValue)
case None => println("Whoops, didn't get anything useful back")
}
But, a bit verbose.
I prefer to map an Option in the following way:
Option(getSomething()) map (something -> doSomethingWith(something))
One liner, short, clear.
The reason to that is Option can be viewed as some kind of collection – some special snowflake of a collection that contains either zero elements or exactly one element of a type and as as you can map a List[A] to a List[B], you can map an Option[A] to an Option[B]. This means that if your instance of Option[A] is defined, i.e. it is Some[A], the result is Some[B], otherwise it is None. It's really powerful!