This is a simple scala code for checking prime number.
When I compile at command prompt, I get the following warning. I thought I would care less for warning. But it didn't create the .class files.
Can someone share what this warning means?
warning: This catches all Throwables. If this is really intended, use case _ : Throwable to clear this warning.
object PrimeNumber extends App {
println("11 is prime number : " + checkPrimeNumber(11))
println("111 is prime number : " + checkPrimeNumber(111))
//Method for checking prime numbers between 1 and 100
def checkPrimeNumber(num: Int) = {
try {
if (num < 1 || num > 100)
throw new IllegalArgumentException("Number should be between 1 and 100")
else
isPrimeNumber(num)
} catch {
case e: IllegalArgumentException => e.printStackTrace()
case _ => println("Exception has occurred!")
}
}
//Non Functional Method for finding prime number
def isPrimeNumber(number: Int): Boolean = {
var i = 2
while (i <= number / 2) {
if (number % i == 0) {
return false
}
i += 1
}
true
}
}
It is dangerous to catch Throwable in Java, and even more in Scala.
Instead, use this:
catch { case scala.util.control.NonFatal(e) => // do something }
See http://www.tzavellas.com/techblog/2010/09/20/catching-throwable-in-scala/
Related
I am a newbie for Scala and now am trying to complete an exercise. How can I return an InvalidCartException while the function return type is Try[Price]
//Success: return the calculated price
//Failure: InvalidCartException
def calculateCartPrice(cart:Cart): Try[Price] = {
if(isCartValid(cart)) {
//Calculations happen here
return Try(Price(totalPrice));
}
}
def isCartValid(cart: Cart): Boolean = {
//THIS WORKS FINE
}
Thank you for the help
If you mean "how to make the Try contain an exception", then use the Failure() like below:
def calculateCartPrice(cart:Cart): Try[Price] = {
if(isCartValid(cart)) {
//Calculations happen here
Success(Price(totalPrice));
} else {
Failure(new InvalidCartException())
}
}
Then, given a Try you can use getOrElse to get the value of success or throw the exception.
Try will catch the exception for you, so put the code that can throw the exception in there. For example
def divideOneBy(x: Int): Try[Int] = Try { 1 / x}
divideOneBy(0) // Failure(java.lang.ArithmeticException: / by zero)
If what you have is a Try and you want to throw the exception when you have a Failure, then you can use pattern matching to do that:
val result = divideByOne(0)
result match {
case Failure(exception) => throw exception
case Success(_) => // What happens here?
}
The Neophyte's Guide to Scala has lots of useful information for people new to Scala (I found it invaluable when I was learning).
I'm attempting to perform some retry logic with Scala. For the sake of providing a MRE, I have replaced the exception-throwing object with Y. When running X.main. I expect to see this print two failure messages, then one success message, but it appears that the return statement is effectively acting as a no-op, and I'm seeing 3 success messages.
I realize this isn't idiomatic Scala and there are plenty of other ways to accomplish this, but is there no way to return from within a for loop in Scala? If not, why is that?
object X {
def main(args : Array[String]) : Unit = {
val y = new Y()
for ( i <- 1 to 5 ) {
try {
y.doSomething()
return
} catch {
case e : Throwable =>
if ( i == 5 ) {
throw e
}
}
}
}
}
class Y {
var counter = 0
def doSomething() : Unit = {
if ( counter < 2 ) {
println("Tried to do something, but failed")
counter += 1
throw new RuntimeException
}
println("Did something")
}
}
return is even more weird than you thought, not just "non-idiomatic".
It actually throws an exception. Your catch clause catches and swallows it. That's why it "acts as no-op".
Don't do this. Please.
But, if you insist, do, at least catch { case NonFatal(e) => instead as suggested in the comment - that would let through the exceptions thrown by return.
My code throw exception scala.util.control.BreakControl, but I don't know why. Does anyone know?
Some place I use breakable and break, but I don't why cause this exception.
fragment 1
breakable {
for (quaOfLine <- dataOfLine) {
try {
// ... some other code
if (judgeTime(jsonQua.getInt("startTime")) == judgeTime(jsonLine.getInt("startTime"))) {
// ... some other code
if (quaRRIDs.length / RRIDs.length.toFloat >= 0.8 || quaRRIDs.length / RRIDs.length.toFloat <= 1.2) {
var count = 0
breakable {
for (rrid <- RRIDs) {
for (quaRRID <- quaRRIDs) {
if (rrid == quaRRID) {
count += 1
break //break
}
}
}
}
if (count / RRIDs.length.toFloat >= 0.8) {
sameLine = qualifier + "::" + value
break // break
}
}
}
} catch {
case e: Throwable => e.printStackTrace
}
}
}
fragment 2
breakable {
for (quaOfDest <- dataOfDest) {
try {
val qualifier = quaOfDest.getString("qualifier")
val value = quaOfDest.getString("value")
val jsonQua = new JSONObject(value)
val (quaSLon, quaSLat, quaELon, quaELat) = getSELonLat(jsonQua)
if (jsonQua.getInt("timeBucket").toString == judgeTime(jsonLine.getInt("startTime"))) {
someDest = qualifier + "::" + value
break //break
}
} catch {
case e: Throwable => e.printStackTrace
}
}
}
scala.util.control.BreakControl is thrown by the method scala.util.control.Breaks.break. It is used for simulating the break statement from Java. It is used like this:
import scala.util.control.Breaks.{break, breakable}
breakable {
for(i <- 1 until 10) {
println(i)
if(i > 5) break
}
}
BreakControl is a private class so normally it won't be thrown by anything else than break.
This also means that inside a breakable block you shouldn't catch BreakControl yourself. You break inside a try block and then catch all Throwables and print them. BreakControl is a Throwable so it will be caught by you instead of by the breakable method.
If you really want to catch all Exceptions/Throwables, you should do something like this:
import scala.util.control.Breaks.{break, breakable}
import scala.util.control.ControlThrowable
breakable {
for(i <- 1 until 10) {
try {
println(i)
if(i > 5) break
} catch {
case c: ControlThrowable => throw c
case t: Throwable => t.printStackTrace
}
}
}
The Scala Standard Library also includes a special construct for cases like this which lets you catch all Throwables except for fatal ones like OutOfMemoryError or StackOverflowError, and also everything that extends ControlThrowable:
import scala.util.control.NonFatal
try {
//do stuff
} catch {
case NonFatal(e) => e.printStackTrace
}
I have the below requirement where I am checking whether a value is greater than 10 or not and based on that I will break, otherwise I will return a String. Below is my code:
import scala.util.control.Breaks._
class BreakInScala {
val breakException = new RuntimeException("Break happened")
def break = throw breakException
def callMyFunc(x: Int): String = breakable(myFunc(x))
def myFunc(x: Int): String = {
if (x > 10) {
"I am fine"
} else {
break
}
}
}
Now what is the happening is that I am getting the error message saying "type mismatch; found : Unit required: String" The reason is :
def breakable(op: => Unit)
But then how I will write a function which can return value as well as break if required?
The Scala compiler can evaluate that a branch throws an exception and not use it to form a minimum bound for the return type, but not if you move the throwing code out in a method: since it can be overridden, the compiler cannot be sure it will actually never return.
Your usage of the Break constructs seems confused: it already provides a break method, there is no need to provide your own, unless you want to throw your exception instead, which would make using Break unnecessary.
You are left with a couple of options then, since I believe usage of Break is unnecessary in your case.
1) Simply throw an exception on failure
def myFunc(x: Int): String = {
if (x > 10) {
"I am fine"
} else {
throw new RuntimeException("Break happened")
}
}
def usemyFunc(): Unit = {
try {
println("myFunc(11) is " + myFunc(11))
println("myFunc(5) is " + myFunc(5))
} catch {
case e: Throwable => println("myFunc failed with " + e)
}
}
2) Use the Try class (available from Scala 2.10) to return either a value or an exception. This differs from the previous suggestion because it forces the caller to inspect the result and check whether a value is available or not, but makes using the result a bit more cumbersome
import scala.util.Try
def myFunc(x: Int): Try[String] = {
Try {
if (x > 10) {
"I am fine"
} else {
throw new RuntimeException("Break happened")
}
}
}
def useMyFunc(): Unit = {
myFunc match {
case Try.Success(s) => println("myFunc succeded with " + s)
case Try.Failure(e) => println("myFunc failed with " + e)
}
}
3) If the thrown exception isn't relevant, you can use the Option class instead.
You can see how the multiple ways of working with Options relate to each other in
this great cheat sheet.
def myFunc(x: Int): Option[String] = {
if (x > 10) {
Some("I am fine") /* Some(value) creates an Option containing value */
} else {
None /* None represents an Option that has no value */
}
}
/* There are multiple ways to work with Option instances.
One of them is using pattern matching. */
def useMyFunc(): Unit = {
myFunc(10) match {
case Some(s) => println("myFunc succeded with " + s)
case None => println("myFunc failed")
}
}
/* Another one is using the map, flatMap, getOrElse, etc methods.
They usually take a function as a parameter, which is only executed
if some condition is met.
map only runs the received function if the Option contains a value,
and passes said value as a parameter to it. It then takes the result
of the function application, and creates a new Option containing it.
getOrElse checks if the Option contains a value. If it does, it is returned
directly. If it does not, then the result of the function passed to it
is returned instead.
Chaining map and getOrElse is a common idiom meaning roughly 'transform the value
contained in this Option using this code, but if there is no value, return whatever
this other piece of code returns instead'.
*/
def useMyFunc2(): Unit = {
val toPrint = myFunc(10).map{ s =>
"myFunc(10) succeded with " + s
}.getOrElse{
"myFunc(10) failed"
}
/* toPrint now contains a message to be printed, depending on whether myFunc
returned a value or not. The Scala compiler is smart enough to infer that
both code paths return String, and make toPrint a String as well. */
println(toPrint)
}
This is a slightly odd way of doing things (throwing an exception), an alternative way of doing this might be to define a "partial function" (a function which is only defined only a specific subset of it's domain a bit like this:
scala> val partial = new PartialFunction[Int, String] {
| def apply(i : Int) = "some string"
| def isDefinedAt(i : Int) = i < 10
}
partial: PartialFunction[Int, String] = <function1>
Once you've defined the function, you can then "lift" it into an Option of type Int, by doing the following:
scala> val partialLifted = partial.lift
partialOpt: Int => Option[String] = <function1>
Then, if you call the function with a value outside your range, you'll get a "None" as a return value, otherwise you'll get your string return value. This makes it much easier to apply flatMaps/ getOrElse logic to the function without having to throw exceptions all over the place...
scala> partialLifted(45)
res7: Option[String] = None
scala> partialLifted(10)
res8: Option[String] = Some(return string)
IMO, this is a slightly more functional way of doing things...hope it helps
I'm new to Scala continuations, and relatively new to the scala language in general.
I tried playing with Scala continuations and wrote the following code:
case class MyException(msg:String) extends Exception
def go:Int = reset {
println("enter your input")
val my_check = //try
{
val user_input = readLine()
if (!user_input.matches("\\w+")) {
throw new MyException("illegal string: " + user_input)
}
shift {
k: (Boolean => Int) => {
if (user_input == "true") {
k(true)
}
else if (user_input == "false") {
k(false)
}
else {
// don't even continue
0
}
}
}
}
// catch {
// case MyException(msg) => false
// }
if (my_check) {
println("TRUE")
1
}
else {
println("FALSE")
-1
}
}
println(go)
The code worked as expected: when the user enters a non-alphanumeric string a MyException is thrown, when the user enters "true" the code continues with my_check = true, when the user enters "false" the code continues with my_check = false, and when the user enters an alphanumeric string which is not "true" nor "false" the go function exits with 0.
Then I tried wrapping some of the code in a try-catch block (where the comments are), and the compilation failed with:
error: found cps expression in non-cps position
val my_check = try
I understand there's a problem with "injecting" an exception into a continuation, but why can't I simply put the shifted call inside a try-catch block?
I need this in the framework I'm planning, in which the programmer will not be aware that his code is used in a continuation form (he'll call some function which he would think to be "normal", but will actually do the shift).
Obviously, I need him to be able to call the function inside a try-catch block, even though the shifted call itself will not raise an exception.
Can this issue be solved with ControlContext?
Will it help if I add some "typing" rules on the values (maybe with the #cps[..])?
I already thought about the alternative of using Actors so you won't get any credit for that :)
Thanks,
(P.S. I'm using Scala 2.9.2, and obviously use the -P:continuations:enable flag)
Thanks #som-snytt, but your solution was somewhat far from a generic one. I can't demand the framework user to write def my_check instead of val my_check every time it uses a try-catch block.
However, I played with your solution, and built the following code:
import scala.util.continuations._
case class MyException(msg:String) extends Exception
object try_protector {
def apply[A,B](comp: => A #cps[B]):A #cps[B] = {
comp
}
}
object Test extends App {
def go: Int = reset {
println("enter your input")
val my_check = try_protector {
try {
val user_input = readLine()
if (!user_input.matches("\\w+")) {
throw new MyException("illegal string: " + user_input)
}
shift {
k: (Boolean => Int) => {
user_input match {
case "true" => k(true)
case "false" => k(false)
case _ => 0
}
}
}
} catch {
case MyException(msg) => false
}
}
if (my_check) {
println("TRUE")
1
} else {
println("FALSE")
-1
}
}
println(go)
}
And it works! (on scala 2.9.2)
The user just has to wrap his try-catch block with a try_protector and the code will compile.
Don't ask me how or why... It looks like compilation VODOU to me...
I haven't tried it on scala 2.10.