The Scala Specification states:
A binding has a scope in which the entity defined by a single name can
be accessed using a simple name. Scopes are nested. A binding in some
inner scope shadows bindings of lower precedence in the same scope as
well as bindings of the same or lower precedence in outer scopes.
You have one scope for Trouble
defined inside the method, and another for an object defined inside the package. Since each of these scopes is independent, there are no name collisions.
If you moved the definition of your Trouble
object into the method scope:
object ScalaTest {
def main(args: Array[String]) {
object Trouble {
def apply(i: Int) = println("in trouble")
}
val Trouble = Array(1, 2, 3, 4)
println(Trouble(2))
}
}
Then the compiler would complain:
Error:(9, 9) Trouble is already defined as object Trouble
val Trouble = Array(1, 2, 3, 4)
^
Note that it is discuraged to use pascal case for variable names. One can quickly get confused as types that have an unapply
method may also be used for type decomposition, for example:
object Trouble {
def unapply(ints: Array[Int]): Option[Int] = Some(ints(0))
def apply(i: Int) = println("in trouble")
}
Now when you run:
object ScalaTest {
def main(args: Array[String]) {
val Trouble() = Array(1, 2, 3, 4)
println(Trouble(2))
}
}
The results are completely different:
in trouble
()