trait DAOContract[T <: Entity] {
// default create
def create(t: T): Option[Int]
}
trait UserContract extends DAOContract[User] {
// provide alternate create method for transactional blocks
def create(u: User)(implicit ss: Session): Either[String, Int]
...
}
// DAO provides create implementation with embedded session
class UserDAO(implicit val db: Connection)
extends DAO[User] with UserContract {
import db.Driver.Implicit._
import org.scalaquery.ql._
...
}
in a controller
dao.create(model) // boom, no implicit session
I hope I am missing something here: why is the scala compiler unable to differentiate between the 2 create method signatures above?
Basically makes it impossible for me to overload DAO operations without coming up with a different method naming convention for operations that are transactional (i.e. return Either) or standalone.
Or, I’m just going about things in the wrong way, entirely possible…
There are reasons why Scala prohibits that:
Imagine that your
createmethods would be:Then calling
create(x)(y)would be applicable to both of them.Even though the problem in (1.) could be perhaps resolved by if Scala compiler carefully examined of the types of the functions, it’d be very error prone. In such setup it would be very easy for programmers to make mistakes. Forcing different names for the functions ensures that programmers always know what they call.
If change your methods to have the same return type and if you’re willing to take the risky way, you could try something like this:
When an implicit value is available, the corresponding method is called. Otherwise, the method without the “session” argument is called. But I strongly discourage this approach. Just a slight mistake will lead to calling the wrong variant and this will be very hard to debug.