Created
August 2, 2016 16:13
-
-
Save b-studios/5e1cc3d135053c691d09dd2a34f37c01 to your computer and use it in GitHub Desktop.
Nanolibrary for a stateful pimp-my-library pattern.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package object stateful { | |
import scala.collection.mutable | |
trait Stateful { | |
private val cache = mutable.HashMap.empty[Int, Any] | |
// TODO use some reasonable HashMap implementation here | |
// TODO how slow is the reflection here, perform microbenchmarks? | |
protected[stateful] def getStateOrElseUpdate(d: Decorate[_])(s: => d.State): d.State = | |
cache.getOrElseUpdate(System.identityHashCode(d.getClass), s).asInstanceOf[d.State] | |
} | |
// For the companion object | |
trait Decorate[T <: Stateful] { | |
protected val self: T | |
// TODO think about a reasonable name | |
protected[stateful] type State | |
protected def newState: State | |
protected val state: State = self.getStateOrElseUpdate(this)(newState) | |
} | |
} | |
object client { | |
import stateful._ | |
class Foo(n: Int) extends Stateful { | |
def bar = n | |
} | |
implicit class FooOps(protected val self: Foo) extends Decorate[Foo] { | |
// can hide this neither inside pckg stateful, nor make it protected. | |
// are we forced to leak the statetype??? | |
type State = FooState | |
protected def newState = new FooState(self.bar) | |
def inc = { state.x += 1; self } | |
def get = state.x | |
} | |
class FooState(var x: Int) | |
val f = new Foo(13) | |
println(f.bar) | |
println(f.inc.inc.inc.get) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment