Package Scopes
Anders als in Java, wo nur die Package-Namen in einer hierarchischen Struktur angeordnet sind, können in Scala die Packages selbst verschachtelt werden. Das erkennt man am besten, wenn man die folgende Notation wählt:
package a {case object Apackage b {case object B {override def toString = A.toString}}}
In diesem Beispiel befindet sich Package b innerhalb von Package a und daher können wir aus Package b heraus auf das Singleton Object A zugreifen, ohne dieses explizit zu importieren. Das ist in vielen Fällen praktisch und funktioniert gleichermaßen für Scala 2.7 wie 2.8.
Neben dieser etwas speziellen Notation mit geschweiften Klammern bietet Scala auch die von Java bekannte Alternative, in der das package-Statement ohne Klammern vorangestellt wird und sich auf alles unterhalb erstreckt. Obiges Beispiel sieht in Scala 2.7 dann so aus, wobei die beiden Codefragmente auf zwei Dateien verteilt sein sollen:
package acase object Apackage a.bcase object B {override def toString = A.toString}
Im unteren Codefragment interpretiert der Scala-Compiler die Deklaration package a.b als zwei verschachtelte Packages. Genau das ändert sich mit Scala 2.8! Wenn wir dieses Beispiel mit dem neuen Scala-Compiler übersetzen, dann erhalten wir beim unteren Codefragment eine Fehlermeldung “... error: not found: value A ...”. Das liegt daran, dass package a.b seit Scala 2.8 nur noch als ein Package interpretiert wird, nicht mehr als zwei verschachtelte Packages.
Warum werden in Scala 2.8 nicht mehr automatisch alle Packages “aufgespannt”? Das liegt daran, dass verschachtelte Packages übergeordnete Packages verdecken können. So verdeckt z.B. package demo.scala alle Typen der Scala-Library. Dieser Sachverhalt erwies sich in einigen Projekten als reales Problem, das nur durch die sehr unschöne “Root-Package-Notation” gelöst werden kann.
Wenn wir das “alte” Verhalten trotz der damit verbundenen Problematik auch mit Scala 2.8 erreichen wollen, dann können wir nun die Package-Deklaration für das zweite Codefragment folgendermaßen schreiben:
package apackage bcase object B {override def toString = A.toString}
So werden wieder zwei verschachtelte Packages “aufgespannt”.
Package Objects
Nach dieser Änderung kommen wir zu einer echten Neuerung: Mit Scala 2.8 können wir Packages nicht nur implizit anlegen, indem wir Klassen anlegen, die sich in einem Package befinden, sondern explizit durch so genannte Package Objects. Diese können genau wie Singleton Objects Felder, Methoden und Typen definieren. Ein Beispiel:
package object demo {implicit def toOption[T](x: T) =if (x == null) None else Some(x)}
Hier definieren wir mit den Schlüsselwörtern package object das Package Object demo. Alle Member von Package Objects befinden sich im Scope des entsprechenden Packages, d.h. in unserem Beispiel befindet sich die Methode toOption dadurch im Package demo.




