Recently, I often write code:
def doSomethingWithLotsOfConditions(arg1, arg2, arg3...) { arg1.get(arg2) match { case Some(value1) => arg3.get(value1) match { case Some(value2) => arg4.get(arg5, value2) match { case Some(value3) => finallyDoSomethingInside(value3) case None => log("Some excuse for being unable to work with arg4/arg5...") } case None => log("Some excuse for being unable to work with arg3") } case None => log("Some excuse for being unable to work with arg1/arg2") } }
A somewhat related question , apparently, largely advocates such use of nested match , although, from my point of view, it hardly seems readable, concise or easy to understand: (1) it kind of breaks the check itself and its consequences, (2) makes the code unmanaged nested without any real justification for nesting. In these specific cases, I would be happy to structure the code in lines:
def doSomethingWithLotsOfConditions(arg1, arg2, arg3...) { // Step 1 val value1Opt = arg1.get(arg2) if (value1Opt.isEmpty) { log("Some excuse for being unable to work with arg1/arg2") return } val value1 = value1Opt.get // Step 2 val value2Opt = arg3.get(value1) if (value2Opt.isEmpty) { log("Some excuse for being unable to work with arg3") return } val value2 = value2Opt.get // Step 3 val value3Opt = arg4.get(arg5, value2) if (value3Opt.isEmpty) { log("Some excuse for being unable to work with arg4/arg5...") return } val value3 = value3Opt.get // All checked - we're free to act! finallyDoSomethingInside(value3) }
However, this template (i.e. valueXOpt = (...).get => check isEmpty => value = valueXOpt.get ) looks really ugly and also definitely too detailed. Damn, even a Java version would have looked more concise:
Value1Type value1 = arg1.get(arg2); if (value1 != null) { log("Some excuse for being unable to work with arg1/arg2"); return; }
Is there a better, cleaner alternative, that is, to get the value and indicate an alternative short escape route (that is log line + return ) without entering into the nest with matches?