This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 6.7, “How to put common code in Scala package objects.”
Problem
You want to make Scala functions, fields, and other code available at a package level, without requiring a class or object.
Solution
Put the code you want to make available to all classes within a package in a package object.
By convention, put your code in a file named package.scala in the directory where you want your code to be available. For instance, if you want your code to be available to all classes in the com.alvinalexander.myapp.model package, create a file named package.scala in the com/alvinalexander/myapp/model directory of your project. In the package.scala source code, remove the word model
from the end of the package statement, and use that name to declare the name of the package object. Including a blank line, the first three lines of your file will look like this:
package com.alvinalexander.myapp package object model {
Now write the rest of your code as you normally would. The following example shows how to create a field, method, enumeration, and type definition in your package object:
package com.alvinalexander.myapp package object model { // field val MAGIC_NUM = 42 // method def echo(a: Any) { println(a) } // enumeration object Margin extends Enumeration { type Margin = Value val TOP, BOTTOM, LEFT, RIGHT = Value } // type definition type MutableMap[K, V] = scala.collection.mutable.Map[K, V] val MutableMap = scala.collection.mutable.Map }
You can now access this code directly from within other classes, traits, and objects in the package com.alvinalexander.myapp.model as shown here:
package com.alvinalexander.myapp.model object MainDriver extends App { // access our method, constant, and enumeration echo("Hello, world") echo(MAGIC_NUM) echo(Margin.LEFT) // use our MutableMap type (scala.collection.mutable.Map) val mm = MutableMap("name" -> "Al") mm += ("password" -> "123") for ((k,v) <- mm) printf("key: %s, value: %s\n", k, v) }
Discussion
The most confusing part about package objects is where to put them, along with what their package and object names should be.
Where to put them isn’t too hard; by convention, create a file named package.scala in the directory where you want your code to be available. In the example shown, I want the package code to be available in the com.alvinalexander.myapp.model package, so I put the file package.scala in the com/alvinalexander/myapp/model source code directory:
+-- com +-- alvinalexander +-- myapp +-- model +-- package.scala
In regards to the first few lines of the package.scala source code, simply start with the usual name of the package:
package com.alvinalexander.myapp.model
Then take the name of the last package level (model) off that statement, leaving you with this:
package com.alvinalexander.myapp
Then use that name (model
) as the name of your package object:
package object model {
As shown earlier, the first several lines of your package.scala file will look like this:
package com.alvinalexander.myapp package object model {
The Scala package object documentation states, “Any kind of definition that you can put inside a class, you can also put at the top level of a package.” In my experience, package objects are a great place to put methods and functions that are common to the package, as well as constants, enumerations, and implicit conversions.
As described in the second page of the Scala package object documentation, “The standard Scala package also has its package object. Because scala._
is automatically imported into every Scala file, the definitions of this object are available without prefix.” If you create something like a StringBuilder
or Range
, you’re using this code.
See Also
Scala’s root package object is full of type aliases, like these:
type Throwable = java.lang.Throwable type Exception = java.lang.Exception type Error = java.lang.Error type RuntimeException = java.lang.RuntimeException type NullPointerException = java.lang.NullPointerException type ClassCastException = java.lang.ClassCastException
Like the Predef
object, its source code is worth looking at if you want to know more about how Scala works. You can find its source by following the “source” link on its Scaladoc page.
- An introduction to package objects
- The Scala package object
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |