2

Scala version = 2.10.6 Shouldn't this code fail because of re-used identifier?

object ScalaTest {
  def main(args: Array[String]) {
    val Trouble = Array(1, 2, 3, 4)
    println(Trouble(2))
  }
}

object Trouble {
  def apply(i: Int) = println("in trouble")
}

Prints:

3
Dragonborn
  • 1,755
  • 1
  • 16
  • 37
  • 3
    You can't define identifier with the same name in the same scope. In your case, you define identifier with the same name in two different scopes, which is legal. Also see [this question](http://stackoverflow.com/questions/7031106/why-does-scala-support-shadow-variables). – TeWu May 27 '16 at 11:52

1 Answers1

1

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
()
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321