Skip to content

Scalaはオブジェクト階層の遠いところが影響するので嫌い

数時間溶かしたので書いた。

trait AuthConfig {
type User
}
trait AuthConfigImpl extends AuthConfig {
}
trait UserAuthConfigImpl extends AuthConfigImpl {
override type User = DtoUserVisitor
}
trait SingInElement extends BrowserElement with UserAuthConfigImpl {
}
import models.types.user.User
class Orgs extends InjectedController with SignedInElement {
def members() = OrgStackAction(orgUrlName) { implicit req => org =>
// これのコメントを外すとreference to User is ambiguousエラーになる
// import models.types.user.User
val expectedUserIds: Array[EntityKey[User]]
}
}

このとき、Array[EntityKey[User]]User は、コードを書いていたときの意図としては models.types.user.User が参照されると思っていたけれど、実際は UserAuthConfigImpl で定義した DtoUserVisitor が有効になる。

implicit もそうだけど、こういった、オブジェクト階層のどこかで定義されたものが見えないところから刺してくるのが本当に嫌い。せめて User でJump to definitionしたときに override の行へ遷移できればマシだったのだが、少なくとも今はできない。

確かにエラーメッセージには書いてあるが

Terminal window
$ testOnly
[error] src/mackerel3/app/controllers/Kamatari.scala:35:55: type mismatch;
[error] found : models.types.EntityKey[models.types.user.User]
[error] (which expands to) io.mackerel.repo.core.EntityKey[models.types.user.User]
[error] required: io.mackerel.repo.core.EntityKey[KamatariOrgs.this.User]
[error] (which expands to) io.mackerel.repo.core.EntityKey[models.types.user.DtoUserVisitor]
[error] if emptyOrExists(expectedUserIds)(user.teamUser.userId)
[error] ^

KamatariOrgs.this.User がそういったものだと知らなければ無理だろう。