som-snytt
som-snytt

Reputation: 39577

Explain naming precedence again? I'm kind of in a bind

I saw a test case for name binding that made me go huh? so here is a recap of the simple rule. I'm sure this has been reviewed in many blog posts and SO questions.

The test case, object Top, ensures that PrimaryKey is ambiguous.

"Huh?" I thought imports were a "lower priority." Why shouldn't it compile?

Why is it only a problem inside curly braces (see X2)?

package imps

object X {
  object Y {
    val Z = 7
  }
  object A {
    val Z = 9
    import Y.Z
    println(Z)
  }
}

object X2 {
  object Y {
    val Z = 7
  }
  object A {
    val Z = 9
    locally {
      import Y.Z
      println(Z)
    }
  }
}

object Top {
  object ColumnOption {
    object PrimaryKey
  }

  class A {
    def PrimaryKey: Any = ???

    {
      import ColumnOption._

      (null: Any) match { case PrimaryKey => }

      PrimaryKey // was already ambigious in 2.10.3
    }
  }
}

Upvotes: 2

Views: 58

Answers (1)

som-snytt
som-snytt

Reputation: 39577

This is the simple illustration at the beginning of Chapter 2 of the spec. For some reason I had not internalized it, so here it is, externalized.

The test case, object Top, ensures that PrimaryKey is ambiguous.

I thought imports were a "lower priority," so I tried X, which compiles.

But in a nested scope, see X2, the import becomes ambiguous.

The reason is that within a scope, see X, the local Z has higher precedence than the imported Z.

But in the nested scope, the val Z is no longer local to the scope, so it is "in scope" without being "local" to it. Furthermore, the imported Z does not shadow it, as the spec says, because it has a lower precedence. Hence the error about the ambiguous Z.

Upvotes: 1

Related Questions