David R. MacIver's Blog
A cute Scala hack
class 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 .(:6)
at .()
at RequestResult$.(:3)
at RequestResult$.()
at RequestResult$result()
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 .(:6)
at .()
at RequestResult$.(:3)
at RequestResult$.()
at RequestResult$result()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorI...Comments
Ian Clarke on 2008-09-11 16:52:02:
This could just just a hint more explanation.
DavidLG on 2008-09-12 14:56:22:
Combining “update” with pass-by-name! Also an elegant user of Either. Cool.
david on 2008-09-12 19:22:19:
Ian: Nah, not really.