Below I have some scala code that should log "hi" if the argument to example is true. However this logs () 3 times.
class Poplar {
def hello (): String =
"hi"
def example (runHello: Option[Boolean]) {
if (runHello.isDefined) hello
None
}
}
object Main extends App {
val p = new Poplar()
println(p.example(Some(true)))
println(p.example(Some(false)))
println(p.example(None))
}
What is wrong about the above code that doesn't allow the code to log 'hi'?
CodePudding user response:
def example(runHello: Option[Boolean]) {
// code
}
is (deprecated) syntactic sugar for
def example(runHello: Option[Boolean]): Unit = {
// code
}
Unless the -Ywarn-value-discard compiler option (which will reject code like this, which is why it's a very useful compiler option) is in effect, the code block can result in any value: since there's only one possible value for Unit (that value is ()) the "conversion" is trivial (albeit literally one which discards the value).
Your println then prints the value (()) which it receives from calling example, thus the three printings of ().
I would suggest:
changing the result type of
exampletoOption[String]: it will returnSome("hi")if the given option containstrueandNoneotherwiseIn your
main, printing the results usingforeach:
p.example(Some(true)).foreach(println _)
p.example(Some(false)).foreach(println _)
p.example(None).foreach(println _)
CodePudding user response:
With the help of the others in this post I arrived at:
class Poplar {
def hello (): String =
"hi"
def example (runHello: Option[Boolean]): Option[String] = {
val rh = runHello.getOrElse(false)
if (rh) Some(hello)
else None
}
}
object Main extends App {
val p = new Poplar()
println(p.example(Some(true)))
println(p.example(Some(false)))
println(p.example(None))
}
Which will only log "hi" for the first println.
