We often need to pass through the code context information like the user that is performing the action. We use this context for various things like authorization checks. In these cases implicit values can prove to be very useful to reduce boiler plate code.
Let's say we have a simple execution context that we pass around: case class EC(initiatingUser:User)
We can have handy guards:
def onlyAdmins(f: => T)(implicit context:EC) = context match{
case EC(u) if(u.roles.contain(Role.ADMIN)) => f
case _ => throw new UnauthorizedException("Only admins can perform this action")
}
val result = onlyAdmins{
//do something adminy
}
I recently found myself in need to do this when working with Akka actors but they make use of pattern matching and I am yet to find a good way of making implicits work well with extractors.
First you would need to pass the context with every command, but that's easy:
case class DeleteCommand(entityId:Long)(implicit executionContext:EC)
//note that you need to overwrite unapply to extract that context
But the receive function looks like this:
class MyActor extends Actor{
def receive = {
case DeleteCommand(entityId, context) => {
implicit val c = context
sender ! onlyAdmins{
//do something adminy that also uses context
}
}
}
}
It would be much simpler if extracted variables could be marked as implicit but I haven't seen this feature:
def receive = {
case DeleteCommand(entityId, implicit context) => sender ! onlyAdmins{
//do something adminy (that also uses context)
}
}
Are you aware of any alternative ways of coding this so it reduces the boilerplate code?