Using scala.sys.process with Future - scala

I am trying to execute something like this
scala> import scala.sys.process._
scala> Process("cat temp.txt")!
I will be doing this say in a Play Framework REST handler. I want this to return a future object so that I can map/flatMap on it and do further processing when the shell is done executing. How do I do that?

I think all you need is this.
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.sys.process._
val fs = Future("cat temp.txt".!!) // Future[String] = Future(<not completed>)
The file contents becomes one long string but you can split() it in the map() operation.

Related

Future Not Completed But Looks Like it Has

I am a Scala newbie trying to understand Futures. I typed in the following in the REPL:
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> val m = Future(println("Message"))
Message
m: scala.concurrent.Future[Unit] = Future(<not completed>)
scala> Future(println("Another Message"))
res4: scala.concurrent.Future[Unit] = Future(<not completed>)
Another Message
In the first case I am assigning a Future computation to a variable m. I haven't called m yet but the Future actually produces the "Message" string output. But I also get a Future(<not completed>) message. What is going on here? Has the future completed or not? The string output tells me it has. Can somebody clear this up for me?
A Future will start executing as soon as it is created (Depending on the ExecutionContext implementation and assuming resources are available for it to run.)
The fact that you see your message printed to the console indicates your Futures have completed.
Try the following and see what happens:
Future{
Thread.sleep(5000)
println("Message")
}
It is completed, what you see Future(<not completed>) is just the `toString() from the Future.
try:
import scala.concurrent.ExecutionContext.Implicits.global
val f = scala.concurrent.Future{
println("Message")
}
println(f.toString())
Future execute always eagerly.

Convert List of Cats Effect IO to IO

With Futures, If I have a list of Futures. I can convert them into a single future by doing Future.sequence. but on the cats.effect.IO there is no IO.sequence method.
So if I have a List[IO[Long]] how do I convert it into IO[List[Long]]
Something like that what are you looking for?:
import cats.instances.list._
import cats.syntax.parallel._
val listIo : List[IO[Long]] = ???
listIo.parSequence

Change Java List to Scala Seq?

I have the following list from my configuration:
val markets = Configuration.getStringList("markets");
To create a sequence out of it I write this code:
JavaConverters.asScalaIteratorConverter(markets.iterator()).asScala.toSeq
I wish I could do it in a less verbose way, such as:
markets.toSeq
And then from that list I get the sequence. I will have more configuration in the near future; is there a solution that provides this kind of simplicity?
I want a sequence regardless of the configuration library I am using. I don't want to have the stated verbose solution with the JavaConverters.
JavaConversions is deprecated since Scala 2.12.0. Use JavaConverters; you can import scala.collection.JavaConverters._ to make it less verbose:
import scala.collection.JavaConverters._
val javaList = java.util.Arrays.asList("one", "two")
val scalaSeq = javaList.asScala.toSeq
Yes. Just import implicit conversions:
import java.util
import scala.collection.JavaConversions._
val jlist = new util.ArrayList[String]()
jlist.toSeq

How to import identity operations in scalaz?

syntax.IdOps seems to have no "companion" object to import its implicits (see, selfless pattern), so it's hard to use that in REPL for example:
scala> val selfish = new scalaz.syntax.ToIdOps{} //I don't want to do this, it feels wrong
selfish: scalaz.syntax.ToIdOps = $anon$1#1adfe356
scala> import selfish._
import selfish._
Is there a way to import it?
https://github.com/scalaz/scalaz/blob/v7.1.2/core/src/main/scala/scalaz/syntax/Syntax.scala#L117
You can use scalaz.syntax.id instead of new scalaz.syntax.ToIdOps{}
import scalaz.syntax.id._

Creating a scala Reader from a file

How do you instantiate a scala.util.parsing.input.Reader to read from a file? The API mentions in passing something about PagedSeq and java.io.Reader, but it's not clear at all how to accomplish that.
You create a FileInputStream, pass that to an InputStreamReader and pass that to the apply method of the StreamReader companion object, which returns a StreamReader, a subtype of Reader.
scala> import scala.util.parsing.input.{StreamReader,Reader}
import scala.util.parsing.input.{StreamReader, Reader}
scala> import java.io._
import java.io._
scala> StreamReader(new InputStreamReader(new FileInputStream("test")))
res0: scala.util.parsing.input.StreamReader = scala.util.parsing.input.StreamReader#1e5a0cb