Another Tour of Scala

PackageObjects

The Gist

This isn’t covered by the tour.

My Interpretation

In Scala pre-2.8, a package object could contain only classes and objects. This is essentially how Scala treats Java’s package concept. In 2.8, a package object can contain type aliases and methods as well. Why is this significant?

This allows a much richer definition of what a “package” is than just a grouping of classes and objects; it also allows for some sophisticated code-sharing strategies as well as some innovative ways to reduce boilerplate.

Consider a well-organized web application; you might have a package for all of your controllers and will most likely have some conventions in place for how to implement them. A project I’ve worked on uses Spring MVC’s annotation-based configuration. Every controller ends up looking like this:

There is the same list of imports at the top if each controller. While code-generation is one strategy to deal with this boilerplate, Scala package objects allow us to better describe what the controller package really means:

Here, we alias all of the common classnames to shorter names; this allows any class in this package to reference those names without an explicit import:

Further, we tend to use BaseController as a dumping ground for common functions that don’t really have much to do with the controller classes. This is somewhat common in Java, as is the creation of “Util” classes that have a bunch of static methods; there simply isn’t a better place to put functions related to certain classes, but that don’t belong in any particular class. We can also include some implicits that are generally useful, but potentially dangerous to have in every class of our application:

Note that we’ve used an implicit conversion to turn our nullable java Long into a handy Scala OptionType .

Now, our controller could look like this:

Notice how we’ve used the package object’s features to seamlessly bridge between the “Scala Way” of doing things and the “Java Way”. Before package objects, we’ve have had to import objects with these implicits and methods explicitly, leading to a lot of boilerplate code.

My Thoughts on This Feature

Hands down this is my favorite feature of Scala 2.8. I could use this today to remove a significant amount of code and to hammer home the conventions littered throughout.