I want to place a block of a code into getOrElse method, but I can't:
//1
getOrElse(() => {
println("id is not found: " + x.Id)
new MyClass(-1)
})
//2
getOrElse {
println("id is not found: " + x.Id)
new MyClass(-1)
}
Works fine for me:
scala> None getOrElse { println("AAA")
| 5 }
AAA
res1: Int = 5
BTW, { () => ... } is a function from the empty argument set to something.
Probably here You have problems :
new MyClass(-1)
I dont see much code but this problems.
See this code which works fine:
import scala.io.Source
class Test(x: Int) {
override def toString = "In test "+x
}
object Main extends App {
val test = None
val b = test.getOrElse({
println("not found")
new Test(-1)
})
println(b.toString)
}
Related
I am trying to come up with a better title.
I am new in Chisel and Scala. Below there is a Chisel code defining and testing an module.
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
class DeviceUnderTest extends Module {
val io = IO(new Bundle {
val a = Input(UInt(2.W))
val b = Input(UInt(2.W))
val out = Output(UInt(2.W))
})
io.out := io.a & io.b
}
class WaveformTestWithIteration extends AnyFlatSpec with ChiselScalatestTester {
"WaveformIteration" should "pass" in {
test(new DeviceUnderTest)
.withAnnotations(Seq(WriteVcdAnnotation)) ( dut => // ???
{
for (a <- 0 until 4; b <- 0 until 4) {
dut.io.a.poke(a.U)
dut.io.b.poke(b.U)
dut.clock.step()
}
}
)
}
}
The code line with comments ??? is where I am quite puzzled. Where does the variable dut is defined? It seems an reference to instance gained by new DeviceUnderTest.
test(new DeviceUnderTest).withAnnotations(Seq(WriteVcdAnnotation)) return an TestBuilder[T] with apply method:
class TestBuilder[T <: Module](...) {
...
def apply(testFn: T => Unit): TestResult = {
runTest(defaults.createDefaultTester(dutGen, finalAnnos))(testFn)
}
...
}
So, dut => {...} is a function (T) => Unit? But it does not look like a standard lambda ((x:T) => {...})? Or it is something else?
What is this syntax in scala exactly?
Consider the following boiled-down version with a similar structure:
def test[A](testedThing: A)(testBody: A => Unit): Unit = testBody(testedThing)
What it's essentially doing is taking a value x: A and a function f: A => Unit, and applying f to x to obtain f(x).
Here is how you could use it:
test("foo"){ x =>
println(if x == "foo" then "Success" else "Failure")
} // Success
test("bar"){ x =>
println(if x == "baz" then "Success" else "Failure")
} // Failure
In both cases, the "string under test" is simply passed to the body of the "test".
Now, you could introduce a few more steps between the creation of the value under test and the specification of the body. For example, you could create a TestBuilder[A], which is essentially just a value a with some bells and whistles (in this case, list of "annotations" - plain strings in the following example):
type Annotation = String
case class TestOutcome(annotations: List[Annotation], successful: Boolean)
trait Test:
def run: TestOutcome
// This simply captures the value under test of type `A`
case class TestBuilder[A](
theThingUnderTest: A,
annotations: List[Annotation]
):
// Bells and whistles: adding some metadata
def withAnnotations(moreAnnotations: List[Annotation]): TestBuilder[A] =
TestBuilder(theThingUnderTest, annotations ++ moreAnnotations)
// Combining the value under test with the body of the test produces the
// actual test
def apply(testBody: A => Unit): Test = new Test:
def run =
try {
testBody(theThingUnderTest)
TestOutcome(annotations, true)
} catch {
case t: Throwable => TestOutcome(annotations, false)
}
// This constructs the thing that's being tested, and creates a TestBuilder around it
def test[A](thingUnderTest: A) = TestBuilder(thingUnderTest, Nil)
println(
test("hello")
.withAnnotations(List("size of hello should be 5")){ h =>
assert(h.size == 5)
}
.run
)
println(
test("hello")
.withAnnotations(List("size of hello should be 42")){ h =>
assert(h.size == 42)
}
.run
)
The principle remains the same: test(a) saves the tested value a, then TestBuilder adds some configuration, and once you add a body { thingUnderTest => /* assertStuff */ } to it, you get a full Test, which you can then run to obtain some results (TestOutcomes, in this case). Thus, the above snippet produces
TestOutcome(List(size of hello should be 5),true)
TestOutcome(List(size of hello should be 42),false)
I think I did not notice that sometimes we can omit type declaration in lambda.
class tester{
def apply( fn: (Int) => Int):Int = fn(5)
}
We can write (new tester)(x => {x+1}) instead of (new tester)((x:Int) => {x+1}).
case class dummy(val prop:Seq[Test])
case class Test(val s :String)
case class Result(val s :String)
def myFunc:Result = {
val s = "11,22,33"
val t = Test(s)
val list = dummy(Seq(t))
val code = Option("25")
val result = code.exists(p => {
list.prop.exists(d => d.s.split(",").contains(p))
})
if (result) {
Result("found")
} else {
Result("Not Found")
}
}
I am calling function myFunc, but instead of evaluating a boolean using if/else construct.
Any possible ways to avoid using If else construct
There is nothing wrong with using the if/else, but you could do this:
code
.flatMap(c => list.prop.find(_.s.split(",").contains(c)))
.map(_ => Result("Found")).getOrElse(Result("Not Found"))
The idea here is that instead of returning a Boolean at each stage we are passing an Option along. Then at the end if the Option is defined we can map that into a Result("Found"), and if it is not defined the .getOrElse will return a Result("Not Found").
In the following code, I am reading no. of lines from a file. If something goes wrong, I'll like to close the file pointer. But how can I find out if f contains valid pointer or not?
def countLines(filename:String):Option[Int] = {
try{
val f = Source.fromFile(filename)
println(s"no. of lines ${f.getLines().size}")
Some(f.getLines.size)
} catch {
case ex: FileNotFoundException => {
println(s"file ${filename} not found")
None
}
} finally {
//f might not be a valid pointer depending on when the error occured
}
}
The book I am reading uses var to maintain state (if f is valid or not) but I am trying to avoid it for sake of using only immutable variables.
def countLines(filename:String):Option[Int] = {
var f:Option[Source] = None
try{
f = Some(Source.fromFile(filename))
println(s"no. of lines ${f.get.getLines().size}")
Some(f.get.getLines.size)
} catch {
case ex: FileNotFoundException => {
println(s"file ${filename} not found")
None
}
} finally {
for(i<-f){
println("closing file")
i.close()
}
}
}
A double Try(). This closes the io resource even if the getLines() fails, but only if the fromFile() succeeds.
import scala.util.Try
def countLines(filename: String): Option[Int] =
Try(io.Source.fromFile(filename)).fold(_ => None, {f =>
val count = Try(f.getLines().length)
f.close()
count.toOption
})
What do you think about this?
If you want Scala-way - i think it's good example for your task:
def countLines(filename: String): Try[Int] = Try(Source.fromFile(filename).getLines.toList.size)
def test() = {
val filename = "/etc/passwd"
countLines(filename) match {
case Success(n) => println(n)
case Failure(f) => println(f)
}
}
When n - is a number of our lines, and f - is a Throwable.
How about this:
def countLines(filename: String): Option[Int] = {
val file = Try(Source.fromFile(filename))
val count = file.map(_.getLines().size)
(for {
_ <- count.recoverWith { case _ => file.map(_.close()) }
lineCount <- count
} yield lineCount).toOption
}
Let's analyze it:
If file does not exist we will have failed Try instance and method returns None. In this case you do not need to clear any resources as no actual stream was created.
If getLines fails for any reason or anything else during processing goes south we will close created stream in first line of for comprehension
Hope it helps
Simply, how about this:
def numLines(fileName:String):Option[Int] = {
try {
val f = scala.io.Source.fromFile(fileName)
try { Some(f.getLines.size) }
catch { case ex: IOException =>
Console.err.println("i/o excetion")
None
}
finally { f.close() }
}
catch {
case ex: FileNotFoundException =>
Console.err.println("file not found")
None
}
}
How do I prevent error when someone does not choose one of the options in scala. This is using Map to get options and I tried to implement Try and catch blocks in case options but it does not work. I'm not sure if this is the right way to do it, if there is any other way let me know. The error is Exception in thread "main" java.lang.NumberFormatException: For input string: "e".
object main extends menu {
def main(args: Array[String]): Unit = {
var opt = 0
do { opt = readOption }
while (menu(opt))
}
}
class menu extends database {
def menu(option: Int): Boolean = try {
actionMap.get(option) match {
case Some(a) => a()
case None => println("That didn't work.")
false
}
} catch {
case _: NumberFormatException => true
}
val actionMap = Map[Int, () => Boolean](1 -> cWords, 2 -> cCharacters, 3 -> exit)
def readOption: Int = {
println(
"""|Please select one of the following:
| 1 - Count Words
| 2 - Count Characters in words
| 3 - quit""".stripMargin)
StdIn.readInt()
}
Use scala.util.Try on readInt(),
import scala.io._
import scala.util._
Try(StdIn.readInt()).toOption
// returns Some(123) for input 123
Try(StdIn.readInt()).toOption
// returns None for input 1a3
Thus readOption delivers Option[Int]. Then
def menu(option: Option[Int]): Boolean = option match {
case Some(a) => actionMap(a)()
case None => println("Try again..."); false
}
Note
A more concise version of main,
def main(args: Array[String]): Unit = while (menu(readOption)) ()
Namely, while menu is true do Unit (or () ).
Here is some working implementation:
import scala.io.StdIn
import scala.util.Try
object Main extends Menu with App {
while (menu(readChoice)) ()
}
class Menu {
val actionMap = Map[Int, () => Boolean](1 -> (() => true), 2 -> (() => true), 3 -> (() => false))
def menu(choice: Option[Int]): Boolean = {
choice.flatMap(actionMap.get)
.map(action => action())
.getOrElse({ println("That didn't work."); false })
}
def readChoice: Option[Int] = {
println(
"""|Please select one of the following:
| 1 - Count Words
| 2 - Count Characters in words
| 3 - quit""".stripMargin)
Try(StdIn.readInt).toOption
}
}
For the first, you can mixin App trait to skip main method boilerplate.
You can simplify your do while loop like this, it has to do nothing inside so you either need some expression or block. A Unit value can be your expression that does nothing.
In scala we name classes using camel case, starting with capital letter.
As readInt throws whenever input is wrong you can catch that using Try, that will return Success(result) of Failure(exception) and change this result to an Option to discard the exception.
what happens in menu is shorthand for
choice match {
case Some(number) =>
actionMap.get(number) match {
case Some(action) =>
action()
case None =>
println("That didn't work.")
false
}
case None =>
println("That didn't work.")
false
}
And could be as well written with for
(for {
number <- choice
action <- actionMap.get(number)
} yield {
action()
}) getOrElse {
println("That didn't work.")
false
}
On as sidenote, you named choice of user an "option" which unfortunately is also a scala class used here extensively, I renamed the variables to avoid confusion.
I would make readOption return a Try[Int], (a Try surrounding StdIn.readInt()), then deal with the possible cases in the menu function
In python you can avoid try {} catch {} finally {} boilerplate with with (see What is the python keyword "with" used for?). I remember seeing an alternative to that in Scala, but I can't find it anymore.
It goes along the lines of:
def using[O](r: {def close()})(doit: () => O): O = try {
doit()
} finally {
r.close
}
using(myWriter){() => myWriter.println("something or another")}
Is it built into 2.10, or do I need a separate library for it?
It's almost trivial to make your own that covers almost all use cases (here using 2.10):
implicit class TidyUpAnything[A](val a: A) extends AnyVal {
def tidily[Z](g: A=>Any)(f: A=>Z) = try { f(a) } finally { g(a) }
}
If you want exceptions to pass through, use as is:
scala> Option(null: String).tidily(println){_.get} // Should print None
None
java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:313)
...
and if you want to handle exceptions, use it in conjunction with scala.util.Try:
scala> import scala.util._
scala> Try( Option(null: String).tidily(println){ _.get } )
None
res1: scala.util.Try[String] = Failure(java.util.NoSuchElementException: None.get)
Normally you would make g be something like _.close, but you can do arbitary resource cleanup with it. For example, here we back off a counter by one whenever we finish:
var i = 0
val a = Array(1,2)
a.tidily(_ => i -= 1){ _.foreach(_ => i += 1) }
scala> i
res2: Int = 1