What is the purpose of 'package objects' in Scala?
Instruction: Explain the role of package objects and how they are used in Scala applications.
Updated
In Scala 2, a package object supplies package-level values, methods and type aliases that cannot otherwise be declared directly at the top level. Its public members are accessed as members of the package.
package example {
package object metrics {
type Count = BigInt
def doubled(value: Count): Count = value * 2
}
}
package client {
import example.metrics.{Count, doubled}
@main def packageExample(): Unit = {
val count: Count = BigInt(7)
assert(doubled(count) == 14)
}
}
The example also compiles in Scala 3's compatibility support. Package objects are conventionally placed in package.scala, within the relevant package directory; that filename is a convention, not the language mechanism that makes the declaration a package object. External consumers can import or qualify its members as normal package members. Package definitions
For new Scala 3 code, define methods, values and type aliases directly at package level. Package objects remain available, while the reference documentation describes their eventual deprecation and removal; they are not already unavailable merely because the migration page is headed “Dropped.” Scala 3 package-object migration
Keep package APIs cohesive and avoid unexpected shared mutable state. Moving existing public definitions to top-level source files can change generated JVM names and binary compatibility, so migration requires compatibility checks beyond confirming that source code still compiles.