January, 2016


10
Jan 16

Scala automatic wrapper/delegation with implicits

Back in the Java world, wrapping an existing class for delegation required implementing the same method signatures and then calling the delegator’s method. In scala you can use implicits to easily enrich an existing class, but what if a method that takes your new enriched class now has to call methods on the wrapped object? You can of course expose the wrapped object class, but there is a slicker way again through implicits.

Imaging this scenario:

You have a HttpRequest class, and you’d like to wrap it in ProxiedHttpRequest by adding a proxy server value to it.

class ProxiedHttpRequest(val req:HttpRequest) {
  lazy val proxyServer = InetAddress.getByName("some.proxy.com")
}

you now have a method that relies on ProxiedHttpRequest…

def proxyRequest(req:ProxiedHttpRequest) {
  val where = req.proxyServer
  /*
    Here I need access to original request being wrapped to get the headers  This is ugly
    and I'd prefer to access it as I would a regular HttpRequest req.headers()
  */
  val headers = req.req.headers()
}

The solution is this…

class ProxiedHttpRequest(val req:HttpRequest) {
  lazy val proxyServer = InetAddress.getByName("some.proxy.com")
}</p>

<p>object ProxiedHttpRequest {
  implicit def delegateToOriginalHttpRequest(r:ProxiedHttpRequest):HttpRequest = r.req
}</p>

<p>object Application {
  def proxyRequest(req:ProxiedHttpRequest) {
    val where = req.proxyServer
    val headers = req.headers()  // No more req.req ugliness
  }
}