Scala package private with duplicate name in package hierarchy

612 views Asked by At

So I understand that in Scala, you can define something private within the scope of a specific package by adding the modifier private[packagename] where packagename is (obviously) the name of the package that you wish the reference to be private to.

So, for instance, let's say I have a package com.mycompany.usefulname with some class that has a field declared private[mycompany] - this will be accessible within all things in the com.mycompany.usefulname, as well as other things like perhaps com.mycompany.othername (or things simply in the com.mycompany, if for some reason I put something there).

What I'm wondering is this: if I do an awful design, where I have two different levels of my hierarchy using the same name, such as a package com.mycompany.mycompany, is there a way to specify which mycompany I would want something to be private within? Based on Package private modifier in Scala 2.8, it doesn't seem to be valid to specific private[com.mycompany], so how could I specify which one it would be?

Just to be clear, this is purely out of curiosity, and I'm not actually trying to make something with such an ambiguous name in the class hierarchy.

EDIT: To actually see what this does, I implemented the following hierarchy:

  • mycompany
    • mycompany
      • InnerObject.scala
    • usefulname
      • InnerObject2.scala
    • OuterObject.scala

InnerObject.scala is as follows:

object InnerObject {
  private val privateVal = 7
  private[mycompany] val packagePrivateVal = 8
  val regularVal = 9
}

InnerObject2.scala is virtually identical:

object InnerObject2 {
  private val privateVal = 7
  private[mycompany] val packagePrivateVal = 8
  val regularVal = 9
}

from OuterObject, I could reference:

  • InnerObject.regularVal
  • InnerObject2.packagePrivateVal
  • InnerObject2.regularVal

The regularVal isn't surprising, as this is public. The package private seems to be going up the hierarchy until it finds the first instance that matches the declaration of mycompany. So, can anyone tell me if/how to make it reference the outer one, rather than the inner one?

1

There are 1 answers

1
Michael Zajac On BEST ANSWER

Here is the relevant excerpt (the example under the linked anchor) from the Scala language specification:

The following code illustrates the use of qualified private:

package outerpkg.innerpkg
class Outer {
  class Inner {
    private[Outer] def f()
    private[innerpkg] def g()
    private[outerpkg] def h()
  }
}

Here, accesses to the method f can appear anywhere within OuterClass, but not outside it. Accesses to method g can appear anywhere within the package outerpkg.innerpkg, as would be the case for package-private methods in Java. Finally, accesses to method h can appear anywhere within package outerpkg, including packages contained in it.

There is no other mention of package-private access modifiers anywhere in the specs, at all. From this, I'd gather there is no way to deal with duplicate path nodes in the package name, and Scala will take the inner-most name that it finds, as you say.

In my opinion, that's a good thing, because duplicate names are redundant and confusing.