Dan Li
Dan Li

Reputation: 928

How to avoid overriding a package object in Scala?

Say I have a two-subproject build with subprojects named highlevel and lowlevel; subproject highlevel depends on subproject lowlevel. Both subprojects contribute to the package com.example.foo:

In highlevel/src/main/scala/com/example/foo/package.scala:

package com.example

package object foo {
  def bar = ???
}

In lowlevel/src/main/scala/com/example/foo/package.scala:

package com.example

package object foo {
  def wee = ???
}

The problem I'm having is that when I use com.example.foo in the highlevel project, wee is no longer defined because lowlevel's com.example.foo package object is being "overshadowed" by that of highlevel. Is there any way of having both bar and wee coexist in subproject highlevel?

(For those interested, the use case is when bar and wee are implicit conversions: bar would handle a conversion involving a type defined in highlevel, while wee would handle a conversion involving a type defined in lowlevel. Both subprojects need the low-level type conversion wee.)

Upvotes: 0

Views: 397

Answers (1)

Chris Martin
Chris Martin

Reputation: 30736

A package object is an object; it is not a package. You can't define a package object twice for the same reason that the following code is invalid:

object A
object A

What you can do is rename lowlevel/src/main/scala/com/example/foo/package.scala to lowlevel/src/main/scala/com/example/foo/LowLevel.scala, and change it from a package object to a trait.

Then the high-level package object can inherit it:

package com.example
package object foo extends com.example.foo.LowLevel

It's fairly common to define things in traits so that package objects can be composed this way. Scalaz does it extensively.

Upvotes: 2

Related Questions