A cute Scala hack
September 11th, 2008class ErrRef[S](s : S){ private[this] var contents : Either[Throwable, S] = Right(s); def update(value : =>S){ contents = try { Right(value) } catch { case (e : Throwable) => Left(e) } } def apply() = contents match { case Right(s) => s; case Left(e) => throw e.fillInStackTrace(); } } object ER{ def apply[S](s : S) = new ErrRef(s); }
And using it…
scala> ER(1) res0: ErrRef[Int] = ErrRef@a96606 scala> res0() res1: Int = 1 scala> res0() = 3 scala> res0() res3: Int = 3 scala> res0() = { println("Hello world"); 3} Hello world scala> res0() res5: Int = 3 scala> res0() = error("Lets see what happens here...") scala> res0() java.lang.RuntimeException: Lets see what happens here... at ErrRef.apply(RefExcept.scala:11) at .<init>(<console>:6) at .<clinit>(<console>) at RequestResult$.<init>(<console>:3) at RequestResult$.<clinit>(<console>) at RequestResult$result(<console>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcc... scala> res0() = throw new IllegalArgumentException("Go away") scala> res0() java.lang.IllegalArgumentException: Go away at ErrRef.apply(RefExcept.scala:11) at .<init>(<console>:6) at .<clinit>(<console>) at RequestResult$.<init>(<console>:3) at RequestResult$.<clinit>(<console>) at RequestResult$result(<console>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorI...
September 11th, 2008 at 4:52 pm
This could just just a hint more explanation.
September 12th, 2008 at 2:56 pm
Combining “update” with pass-by-name! Also an elegant user of Either. Cool.
September 12th, 2008 at 7:22 pm
Ian: Nah, not really.