Scala Tutorial - Learn How To Use Package Object
Overview
In this tutorial, we will learn how use Package Objects to store and encapsulate common Objects and Implicit conversions.
Objects and Implicit conversions declared inside Package Objects, as the name implies, will be accessible to any classes or traits in the given package. In addition, Package Objects make it easy to inject these Objects and Implicit conversions into other scopes within your application.
Steps
1. How to add JodaTime dependency in build.sbt"
In the Tutorial on Importing Dependencies Using build.sbt, we showed how you can update the libraryDependencies settings key in your build.sbt file so that you can easily import other 3rd party libraries.
In this tutorial, we will import the popular JodaTime library so that we can later alias a new type called DateTime to refer to JodaTime as opposed to default Scala DateTime.
println("\nStep 1: How to add JodaTime dependency in build.sbt")
libraryDependencies ++= Seq(
"joda-time" % "joda-time" % "2.9.3",
"org.joda" % "joda-convert" % "1.8"
)
2. How to define a case class to represent a Donut object in a package object
Before we can declare a case class inside a Package Object you must first create it! In IntelliJ's Project window, right click on a given package which in our case is the package named four and select New-> Package Object.
package object four {
println("Step 2: How to define a case class to represent a Donut object in a package object")
case class Donut(name: String, price: Double, productCode: Option[Long] = None)
}
3. How to define an implicit class to augment or extend the Donut object with a uuid field
Next let's declare an Implicit class to extend the functionality of the Donut type which will add an additional uuid method to donut objects.
Obviously since we have access to the Donut case class as per Step 2, we could have easily added a uuid method. But we are simply re-using the example from the tutorial on Implicit Classes,
println("\nStep 3: How to define an implicit class to augment or extend the Donut object with a uuid field")
implicit class AugmentedDonut(donut: Donut) {
def uuid: String = s"${donut.name} - ${donut.productCode.getOrElse(12345)}"
}
4. How to alias JodaTime to a DateTime type
Storing type aliases inside Package Objects is typically a good idea because the type alias will be available package wide. To this end, we can create a DateTime type alias which will refer to the JodaTime we imported from Step 1.
println("\nStep 4: How to alias JodaTime to a DateTime type")
type DateTime = org.joda.time.DateTime
5. How to create instances or objects for the Donut case class from package object
With our Package Object created, we can now create a new Scala Application named PackageObject_Tutorial and instantiate a Donut object without having to add any import statements.
object PackageObject_Tutorial extends App {
println("\nStep 5: How to create instances or objects for the Donut case class from package object")
val vanillaDonut: Donut = Donut("Vanilla", 1.50)
println(s"Vanilla donut name = ${vanillaDonut.name}")
println(s"Vanilla donut price = ${vanillaDonut.price}")
println(s"Vanilla donut produceCode = ${vanillaDonut.productCode}")
println(s"Vanilla donut uuid = ${vanillaDonut.uuid}")
You should see the following output when you run your Scala application in IntelliJ:
Step 5: How to create instances or objects for the Donut case class from package object
Vanilla donut name = Vanilla
Vanilla donut price = 1.5
Vanilla donut produceCode = None
Vanilla donut uuid = Vanilla - 12345
NOTE:
- The Donut type also had access to the Implicit Class which added the uuid method.
6. How to create new JodaTime instance using DateTime alias from package object
We can also create a new DateTime as shown below but keep in mind that DateTime is a type alias to JodaTime.
println("\nStep 6: How to create new JodaTime instance using DateTime alias from package object")
val today = new DateTime()
println(s"today = $today, datetime class = ${today.getClass}")
You should see the following output when you run your Scala application in IntelliJ:
Step 6: How to create new JodaTime instance using DateTime alias from package object
today = 2016-10-17T21:08:57.168+01:00, datetime class = class org.joda.time.DateTime
Summary
In this tutorial, we went over the following:
- How to add JodaTime dependency in build.sbt
- How to define a case class to represent a Donut object in a package object
- How to define an implicit class to augment or extend the Donut object with a uuid field
- How to alias JodaTime to a DateTime type
- How to create instances or objects for the Donut case class from package object
- How to create new JodaTime instance using DateTime alias from package object
Tip
- In Chapter 5, we will learn about traits which you can use to mix-in functionality with Package Object.
- Scala Documentation on Package Object.
Source Code
The source code is available on the allaboutscala GitHub repository.
What's Next
In the next tutorial, I will show you how to use inheritance by extending classes in Scala.