How to use Option[T] to handle null value well in scala? - scala

Java code:
public static Connection connection = null;
public static void main(String[] args) {
if(connection == null){
connection = ConnectionFactory.createConnection(conf);
}
//using connection object to do something
}
converting to Scala code:
someone tell me use Option[T] to handle null value, but I don't how to use Option[T] well, I think it very troublesome.
Scala code:
var connOpt: Option[Connection] = None
def main(args: Array[String]) {
//check `connOpt` Option
connOpt match {
case Some(connection) => { /* using `connection` to do something-----code1 */ }
case _ => {
val connection = ConnectionFactory.createConnection()
connOpt = Option(connection)
// using `connection` to do something------code2
}
}
}
you can see scala code.
I need check connOpt always when I need use connOpt.
code1 and code2 is the same code, I need write two times, I know I can use function to package code1 or code2, but it's very troublesome.
How to handle this case?

I think you can use the 'fold' method to do what you want like this
var connOpt:Option[Connection] = None
def main(args: Array[String]) {
val connection = connOpt.fold(ConnectionFactory.createConnection()){conn => conn}
//using connection object to do something
}
The logic of code mentioned above is the same as your java code that does not write the 'code1' and 'code2' two times.
Using the following example to explain the usage of 'fold'
obj.fold{/*the obj is null, you can return the value you want*/}{a => a
/*if the obj is Some(value), the 'a' is just the 'value'*/
}
Good luck with you

It depends on your business logic; not so much on the programming language.
Does it make sense to keep your component alive if the connection attempt is unsuccessful?
You might want to "fail early": if you can't connect, either throw an Exception or stop your component. In this case, using Option is an unnecessary abstraction.
If your component should survive if it fails to connect, you could do this:
val maybeConn: Option[Connection] = Option(ConnectionFactory.createConnection(conf))
maybeConn foreach doConnRelatedOperation
doOtherOperationThatDoesNotRequireConn
def doConnRelatedOperation(conn: Connection) = println(conn)
def doOtherOperationThatDoesNotRequireConn = "hello!"
In this code example:
Option(ConnectionFactory.createConnection(conf)) will return either Some(conn) or None (I'm assuming createConnection doesn't throw; if it could then maybe you want to use the Try functor instead)
maybeConn foreach doConnRelatedOperation will either do nothing if maybeConn is None or invoke the side-effecting function doConnRelatedOperation that takes a Connection as an argument if maybeConn is Some(conn).
Note that, in this example, doOtherOperationThatDoesNotRequireConn will execute even if there is no connection.
Finally
Let's say your createConnection function might throw an Exception. In that case, Option is the wrong abstraction. In that case, you may want to do lazy val maybeConn: Try[Connection] = Try(ConnectionFactory.createConnection(conf)) instead (basically Try instead of Option).
Note the beautifulness in that the rest of the code doesn't need to be modified! The doConnRelatedOperation function will only be executed if the connection was created, and the doOtherOperationThatDoesNotRequireConn will be executed after, irrespective of having the connection or not. The exception will not affect your code flow!
Welcome to Scala's Good Parts :)

Using Option instead of null is only one of the things "they say" about scala. Your problem is that you chose to use that one (fairly random) piece of advice, and ignore all the others.
The other piece of advice, more relevant in this case is: avoid using state and mutable vars. You can safely throw out both "code 1" and "code 2", and just do this:
lazy val = ConnectionFactory.createConnection(conf)

val connOpt: Option[Connection] = None
def main(args: Array[String]) {
//check `connOpt` Option
connOpt.orElse(Some(ConnectionFactory.createConnection()).map {
connection =>
// code 1
}
}

Related

How to Mock LocalDate.now() in Scala

I have object
object func1{
def something(arg1: Int): String{
// var date = something2()
// Using date
}
def something2(): LocalDate{
LocalDate.now()
}
}
I want to write a test on something method, How can I mock something2
You can't make static methods. So, you need to do something like this:
def something(val now: () => Date = LocalDate.now) = ...
Then, in your production code, you do val foo = something() as you normally would, but in your test, you can do things like
something(_ => new Date(0l)) shouldBe foo
or
val date = mock[Function0[Date]]
when(date.apply()).thenReturn(new Date(0l))
something(date) shouldBe foo
If the code's functionality depends on the time, it's definitely recommended that you have a second look at the code you're testing and explicitly pass a Clock as a parameter or something along those lines (e.g. a function as suggested in other comments) to make its behavior easy to test.
If you are testing this to make sure that a field somewhere indeed contains the time returned by LocalDate.now() please consider that you might be testing the behavior of LocalDate rather than your own code's, so probably mocking that doesn't really give you anything.
If timing is fundamental to the function's behavior and you have no control over it, I believe you might somehow use Mockito's ability to mock static objects. I came up with the following which compiles, but I'm not sure about whether it works or not (since I believe it relies on some bytecode manipulation black magic which might make your testing suite brittle, so beware):
import scala.util.{Try, Using}
import java.time.{Clock, Instant, LocalDate, ZoneId}
import org.mockito.Mockito._
def withClock[A](clock: Clock)(f: => Unit): Try[Unit] = {
Using(mockStatic(classOf[LocalDate])) { mocked =>
mocked.when(() => LocalDate.now()).thenReturn(LocalDate.now(clock))
f
}
}
withClock(Clock.fixed(Instant.ofEpochMilli(42), ZoneId.of("UTC"))) {
assert(LocalDate.now().toEpochDay() == 0)
}

Without using var, what is the way to invalidate a static value in Scala and set it again to new value later

I have made a factory method which should either start a database (cassandra) and connect to it or should return an existing session. The connection to the database is static field.
class EmbeddedCassandraManager {
def getCassandra() = {
if(EmbeddedCassandraManager.cassandraConnection.isDefined) //return existing instance
{
(EmbeddedCassandraManager.testCassandra,EmbeddedCassandraManager.cassandraConnection)
}
else {
EmbeddedCassandraManager.startCassandra()
}
}
def closeCassandra() = {
EmbeddedCassandraManager.closeCassandra()
}
}
object EmbeddedCassandraManager {
val factory = new EmbeddedCassandraFactory
//can I do the logic without using var?
var (testCassandra,cassandraConnection) = startCassandra()
def closeCassandra() = {
cassandraConnection.get.close()
cassandraConnection = None
testCassandra.stop()
}
def startCassandra():(Cassandra,Option[CassandraConnection]) = {
val testCassandra = factory.create()
testCassandra.start()
val cassandraConnectionFactory:DefaultCassandraConnectionFactory = new DefaultCassandraConnectionFactory();
val localCassandraConnection:Option[CassandraConnection] = try{
val connection = cassandraConnectionFactory.create(testCassandra)
Some(connection)
}catch{
case exception:Throwable => {
throw exception
}
}
this.cassandraConnection = localCassandraConnection
(testCassandra,this.cassandraConnection)
}
}
The only way I am able to create the logic is by using a var for the cassandraConnection. Is there a pattern I can use to avoid using var?
In one of the test, I have to stop cassandra to test that the connection doesn't get established if database isn't running. This makes the existing connection stale. Without var, I am not able to set the value to None to invalidate the connection and set it to new value once the database connection is established again.
What is the functional way to create such logic? I need static value of connection so that only one connection is created and I want a way to check that the value is not stale.
Mutability is often unavoidable, because it is an inherent property of the systems we build. However, that doesn't mean that we have to use mutable variables in our code.
There are usually two main ways that you can deal with situations that involve mutable state:
Push the mutable state to a repository outside of your program.
Typical examples of this are "standard" database (if state needs to be persisted) and in-memory storage (if state exists for the duration of your program's lifecycle). Whenever you would fetch a value from such storage, you would treat it as an immutable value. Mutability still exists, but not inside your program, which makes it easier to reason about.
Some people criticize this line of thinking by saying "you are not solving anything, you're just making it some else's problem", and that's true actually. We are letting the database handle the mutability for us. Why not? It's what database is designed to do. Besides, main problem with mutability is reasoning about it, and we are not going to reason about internal implementation of the database. So pushing the mutability from one of our services to another is indeed like throwing the hot potato around, but pushing it to an external system that's designed for it is completely fine.
However, all that being said, it doesn't help your case, because it's not really elegant to store database connection objects in an external storage. Which takes me to point number two.
Use state monad.
If the word "monad" raises some flags for you, pretend I said "use State" (it's quite a simple concept actually, no big words needed). I will be using the implementation of State available in the Cats library, but it exists in other FP libraries as well.
State is a function from some existing state to a new state and some produced value:
S => (S, V)
By going from an existing state to a new state, we achieve the "mutation of state".
Example 1:
Here's some code that uses an integer state which gets incremented by one and produces a string value every time the state changes:
import cats.data.State
val s: State[Int, String] = State((i: Int) => (i + 1, s"Value: $i"))
val program = for {
produced1 <- s
_ = println(produced1) // Value: 42
produced2 <- s
_ = println(produced2) // Value: 43
produced3 <- s
_ = println(produced3) // Value: 44
} yield "Done."
program.run(42).value
That's the gist of it.
Example 2:
For completeness, here's a bigger example which demonstrates a use case similar to yours.
First, let's introduce a simplified model of CassandraConnection (this is just for the sake of example; real object would come from the Cassandra library, so no mutability would exist in our own code).
class CassandraConnection() {
var isOpen: Boolean = false
def connect(): Unit = isOpen = true
def close(): Unit = isOpen = false
}
How should we define the state? Mutable object is obviously the CassandraConnection, and the result value which will be used in for-comprehension could be a simple String.
import cats.data.State
type DbState = State[CassandraConnection, String]
Now let's define some functions for manipulating the state using an existing CassandraConnection object.
val openConnection: DbState = State(connection => {
if (connection.isOpen) {
(connection, "Already connected.")
} else {
val newConnection = new CassandraConnection()
newConnection.connect()
(newConnection, "Connected!")
}
})
val closeConnection: DbState = State(connection => {
connection.close()
(connection, "Closed!")
})
val checkConnection: DbState =
State(connection => {
if (connection.isOpen) (connection, "Connection is open.")
else (connection, "Connection is closed.")
})
And finally, let's play with these functions in the main program:
val program: DbState =
for {
log1 <- checkConnection
_ = println(log1) // Connection is closed.
log2 <- openConnection
_ = println(log2) // Connected!
log3 <- checkConnection
_ = println(log3) // Connection is open.
log4 <- openConnection
_ = println(log4) // Already connected.
log5 <- closeConnection
_ = println(log5) // Closed!
log6 <- checkConnection
_ = println(log6) // Connection is closed.
} yield "Done."
program.run(new CassandraConnection()).value
I know this is not exact code that you could copy/paste into your project and have it work nicely, but I wanted to give a slightly more general answer that might be a bit easier to understand for other readers. With some playing around, I'm sure you can shape it into your own solution. As long as your main program is a for-comprehension on the State level, you can easily open and close your connections and (re)use the same connection objects.
What did we really achieve with this solution? Why is this better than just having a mutable CassandraConnection value?
One big thing is that we achieve referential transparency, which is why this pattern fits into functional programming paradigm nicely, and standard mutability doesn't. Since this answer is already getting a bit long, I will point you towards Cats documentation which explains the whole thing in more detail and demonstrates the benefit of using State very nicely.

Dealing with errors using idiomatic Scala

I'm writing an HTTPS service for a chat bot and find myself dealing with a lot of Futures and Options. Usually if an Option returns None or a Future fails I want to log the exception and reset the user back to the start. Here's a toy example of how I accomplish this:
(for {
user <- userService.retrieve(userId)
userPet <- Future(user.userPet.get)
_ <- sendTextAsJson(s"You're holding a $userPet!")
} yield {}).recover {
case ex: Exception =>
log.error(ex.toString)
fail
}
This works fine but it feels a little weird to wrap things in Future just so their exceptions are swallowed and dealt with in the recover block. It also feels weird to include an empty yield block. Is there a better way?
What you basically do is using onSuccess or onFailure to retrieve the futures result. What you also might try is Try.
There is an example of the underlying functionality.
http://www.scala-lang.org/api/2.9.3/scala/util/Try.html
I might suggest you this article: http://docs.scala-lang.org/overviews/core/futures.html I can't summarize whats stated there in a few sentences. But if you look to the table of contents on the right side, the point Futures explains what happens and how to handle it is stated under Excepetions. Thats the idiomatic way.
I don't think it's too bad tbh, assuming userService.retrieve() returns a Future in the first place. I'd personnally rather use map in this case to make things a bit more explicit :
val futureMsg = userService.retrieve(userId)
.map(user => sendTextAsJson(s"You're holding a ${user.userPet.get}!")
.recover {
case NonFatal(ex) => //Look it up ;)
log.error(ex.toString)
fail
}
You now have Future[Unit] to do whatever you want with.
I agree with you that that's an awkward use of a for-comprehension. This is how I would write this:
import scala.util.control.NonFatal
userService.retrieve(userId)
.map(_.userPet.get)
.map(userPet => s"You're holding a $userPet!")
.flatMap(sendTextAsJson)
.recover {
case NonFatal(ex) =>
log.error(ex.toString)
fail
}
Looking at your sendTextAsJson and fail functions you seem to want to side-effect when the future completes. I would not use map after you perform the Option.get and instead look at Futures onComplete method to either handle the success of the future or handle the exception throw. I am not sure how this way and recover are different though so double check that. I did like #sascha10000 link to the scala doc futures. Its been a long time since I read that but its a good resource from what I remember
Example implementation of your code with onComplete:
import scala.concurrent.Future
import scala.util.{Failure, Success}
import scala.concurrent.ExecutionContext.Implicits.global
object UserFuture extends App {
def fail = println("failed")
def sendTextAsJson(message: String): Unit = println(message)
case class User(userPet: Option[String])
object userService {
def userPet = Some("dog")
val someUser = User(userPet)
def retrieve(userId: Int): Future[User] = Future {
someUser
}
}
def getPet(userId: Int): Unit = {
userService.retrieve(userId)
.map(user => user.userPet.get)
.onComplete {
case Success(userPet) => sendTextAsJson(s"You're holding a $userPet!")
case Failure(ex) => println(ex.toString); fail
}
}
getPet(1)
Thread.sleep(10000) // I forgot how to use Await. This is just here to be able to make sure we see some printouts in the console.
}

Scala DRYing try/catch

I find myself repeating simple try/catch blocks that should, IMO, be 1-liners.
For example, let's say I need to convert a uri string date in yyyymmdd format to Joda-Time. With a standard try/catch block the conversion method looks like:
def ymd2Date(ymd: Option[String]) = ymd match {
case Some(date) =>
try { Right( ymdFormat.parseDateTime(date) ) }
catch { case e =>
log.info(e.getMessage)
Left(None)
}
case None =>
Left(None) // no uri date param
}
val ymdFormat = DateTimeFormat.forPattern("yyyyMMdd")
Works well enough, intent is clear, but when I do this kind of try/catch logging for all non-critical events, then I seek a way to DRY it out. The search led me to this SO post on scala.util.control.Exception. Helpful, but it's still a bit difficult to grok/make it work in the way I'd like it to. In plain English I just want to say, "catch some-action get-result log-error-type".
So, I hacked this out based on the part of control.Exception I'm interested in (or understand to be useful):
class Catcher[T](f: => T) {
type Logger = (=> Any) => Unit
def either[T]( logger: => Logger ) = {
try { Right(f) }
catch { case e =>
logger(e.getMessage)
Left(None)
}
}
}
def catching[T](f: => T) = new Catcher(f)
And then use in place of try/catch like so:
catching( ymdFormat.parseDateTime(date) ) either log.info
Can add on option, a msg prefix, etc., but...it would probably be better to find a way to get control.Exception to work like the above, as the TypeSafe crew is going to produce code worlds better than I'll ever imagine writing.
Does anyone know how to create this kind of syntax using control.Exception where one can pass in a logger function by-name to be used in the catch block?
Would be great if there was a "use cases" for control.Exception, but I get the feeling this utility is for more advanced Scala devs
This should do what you want:
import scala.util.control.Exception
def log(logger: => Logger)(e: Throwable) = {
logger(e.getMessage)
None
}
Exception.allCatch withApply log(logger) apply Some(ymdFormat.parseDateTime(date))
But this kind of stuff is better handled by Scalaz Validation, in my opinion.
A quick example:
import scala.util.control.Exception._
def throwingStuff {
throw new Exception("Hello World!")
}
catching(classOf[Exception]).withApply{err => println(err.toString); None}.apply(Some(throwingStuff))
You can use withApply to override the application logic of the Catch class to do something such as writing to a log.

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.