Can someone help me understand the code in NoStackTrace.scala ?
There is a trait defined named NoStackTrace which I’m using in my code as follows.
def block[A](body:(A=>Nothing)=>A):A = {
// CL like block/return, the name of the return() function is provided
// by the caller.
// Usage: block{ ret => ... ret(someValue) ...}
// extending Exception with NoStackTrace prevents throwing the
// exception from computing the stacktrace and storing the information.
// We don't need a stacktrace because the purpose of this exception
// is simply to perform a non-local exit.
import scala.util.control.NoStackTrace
class NonLocalExit(val data:A) extends Exception with NoStackTrace {}
def ret(data:A):Nothing = {
throw new NonLocalExit(data)
}
try{
body(ret)
}
catch{
case nonLocalExit: NonLocalExit => nonLocalExit.data
}
}
The purpose is to prevent the java fillInStackTrace method from begin called when a particular exception is constructed. However, the code in the trait definition has some exception to this rule (no pun intended) based on sys.SystemProperties.noTraceSupression.
What’s the idea behind scala.sys.SystemProperties and why is that built into this trait as a backdoor?
Here is the code I see in NoStackTrace.scala when I jump to there in IntelliJ.
/** A trait for exceptions which, for efficiency reasons, do not
* fill in the stack trace. Stack trace suppression can be disabled
* on a global basis via a system property wrapper in
* [[scala.sys.SystemProperties]].
*
* @note Since JDK 1.7, a similar effect can be achieved with `class Ex extends Throwable(..., writableStackTrace = false)`
*
* @author Paul Phillips
* @since 2.8
*/
trait NoStackTrace extends Throwable {
override def fillInStackTrace(): Throwable =
if (NoStackTrace.noSuppression) super.fillInStackTrace()
else this
}
object NoStackTrace {
final def noSuppression = _noSuppression
// two-stage init to make checkinit happy, since sys.SystemProperties.noTraceSuppression.value calls back into NoStackTrace.noSuppression
final private var _noSuppression = false
_noSuppression = sys.SystemProperties.noTraceSuppression.value
}