#scala
#scala
Вопрос:
У меня есть следующий код, я не хочу использовать var SysProc есть ли функциональный способ сделать это?
var proc: SysProc = null
try {
proc = SysProc(scalaTestCommand).run(ProcessLogger(out.append, out.append))
forkProcess(proc, Settings.scalaTestTimeout)
} catch {
case e: TimeoutException =>
val msg = "Timeout when running ScalaTestn" out.toString()
logError(msg)
proc.destroy()
sys.error(msg)
case e: Throwable =>
val msg = "Error occurred while running the ScalaTest commandn" e.toString "n" out.toString()
logError(msg)
proc.destroy()
throw e
} finally {
println(out.toString)
if (proc != null) {
println("Exit process: " proc.exitValue())
}
}
Ответ №1:
Технически, если ваш SysProc
конструктор выдает ошибку во время построения, var не будет установлен, так что вы уже можете сделать что-то вроде этого:
try {
val proc = SysProc(scalaTestCommand).run(ProcessLogger(out.append, out.append))
try {
forkProcess(proc, Settings.scalaTestTimeout)
} finally {
proc.destroy()
println("Exit process: " proc.exitValue())
}
} catch {
case e: TimeoutException =>
val msg = "Timeout when running ScalaTestn" out.toString()
logError(msg)
sys.error(msg)
case e: Throwable =>
val msg = "Error occurred while running the ScalaTest commandn" e.toString "n" out.toString()
logError(msg)
throw e
}
и это уже код без переменных.
Если вы хотите быть еще более функциональным, вы можете рассмотреть что-то вроде cats.effect.Resource
и cats.effect.IO
:
Resource {
// how to acquire resource
IO(SysProc(scalaTestCommand).run(ProcessLogger(out.append, out.append)))
} { proc =>
// how release resource when it is not needed
// - no matter if it was used successfuly or not
IO {
proc.destroy()
println("Exit process: " proc.exitValue())
}
} // defines resource
.use(forkProcess(_, Settings.scalaTestTimeout)) // create-use-release resource
.handleErrorWith {
case e: TimeoutException =>
val msg = s"Timeout when running ScalaTestn$out"
IO(logError(msg)) >> IO(sys.error(msg))
case e: Throwable =>
val msg = s"Error occurred while running the ScalaTest commandn$en$out"
IO(logError(msg)) >> IO.raiseError(e)
} // handle errors if happened
.unsafeRunSync // run computation (in this case synchronously)