Last active
May 17, 2018 19:28
-
-
Save bartschuller/4687387 to your computer and use it in GitHub Desktop.
Using Scala's Dynamic trait and reflection to implement delegation. If we swap reflection for macros it will be fast and typesafe again. I guess this could then replace the AutoProxy compiler plugin.
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
name := "delegation" | |
scalaVersion := "2.10.0" | |
libraryDependencies <+= (scalaVersion)("org.scala-lang" % "scala-reflect" % _) |
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
import scala.language.dynamics | |
import reflect.ClassTag | |
import scala.reflect.runtime.universe._ | |
trait Runner { | |
def runAway() | |
} | |
class Player extends Runner { | |
def runAway() { | |
println("Running away") | |
} | |
} | |
class Thrower[T <: Runner](val self: T) { | |
def throwBall() { | |
println("Ball thrown") | |
self.runAway() | |
} | |
} | |
object Main { | |
def main(args: Array[String]) { | |
val player = new Player with Delegate[Thrower[Player]] | |
player.delegate = new Thrower[Player](player) | |
player.throwBall() | |
} | |
} | |
// Naming it HasDelegate would be more correct, but this reads better: | |
// "with Delegate" | |
trait Delegate[T] extends Dynamic { | |
var delegate: T = _ | |
import scala.reflect.runtime.{universe => ru} | |
def applyDynamic(method: String)(args: Any*)(implicit tTag: TypeTag[T], cTag: ClassTag[T]) = { | |
val m = ru.runtimeMirror(delegate.getClass.getClassLoader) | |
val sym = ru.typeTag[T].tpe.declaration(ru.newTermName(method)).asMethod | |
val im = m.reflect(delegate) | |
val methodMirror = im.reflectMethod(sym) | |
methodMirror.apply(args:_*) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment