How to import a package object?

As the title said, how can I import just the package object?
I defined a package object related to the package foo.bar and defined some classes in the folder foo/bar/, how to just import the package object in from another package?

thanks for your help.

Basically, you don’t – there isn’t any way to do that. But there also isn’t any reason to do that: AFAIK, there is no use case for importing just the package object. Can you describe in more detail what you’re trying to accomplish?

package object p extends Runnable {
  def run() = ()
}
package p {
  class C
}
package q {
  import p.{`package` => pp}
  class D {
    def apply() = pp.run()
  }
}
1 Like

blink – TIL. I don’t think I’ve ever seen that construction before. Although I’m still not sure of the use case: couldn’t you just say p.run()?

The request was to

import p.`package`.*

(Using asterisk under -Xsource:3.)

I was going to be fancy and add

package p {
  object `package` {
    def run() = ()
  }
  class C {
    def apply() = run()
  }
}
package q {
  import p.`package`.*
  class D {
    def apply() = run()
  }
}

to show that a package object is an object named package (in a like-named packaging). C sees run without a prefix.

You can have an object named package anywhere, but without special powers, somewhat like an object that is not a class companion.

I see now that the alt syntax is not in the spec. That must be an oversight.

By coincidence, I am just now reworking “deprecate a package” which relies on deprecating the package object. I don’t know offhand if Scala 3 supports deprecating a package by other means; otherwise package objects are deprecated; though top-level definitions generate similar artifacts implicitly.

my question is whethet I can just import a package folder to use the package object like below:

here p is a pakckage:

package foo.bar.p
object foo{}
class bar{}

then what would happen if I just import the package folder itself?

import foo.bar.p

can this work? I know in Java it doesnt work and throws an error. but now that scala has package object, I thought this action could import the package object

you mean the package object is usually used by the class or object in that package and we always directly import those classes or objects rather than the package object itself?

Kind of. More precisely, I think you’re too focused on importing things, and that isn’t what import does – all it does is alias a name so that you don’t have to fully-qualify it everywhere. You don’t need a package object at all – you can just import the package. That’s always true, regardless of whether there is a package object or not. (Which there often isn’t: I use package objects in a fairly small fraction of my packages.)

I’ve literally never seen a package object per se imported, in 15 years of doing Scala, until this thread. You just import the package, or the things in the package.

can I just import a package like foo.bar if foo and bar both are packages?
I notice this question is that when I use java, if I just import package like foo.bar, this will throw an error. so I just wanna know how scala treat this action now that scala has package object.

Thanks for your help.

I think it is not really clear what exactly you are trying to do.

I think it would help if you show the directory structure you have, which files you have, the contents of those files, and then you can explicitly tell us "I want to import xxx in yyy so I can access zzz"

Again I have to keep recommending Chapter 12 “Packages, Imports and Exports” of “Programming in Scala 5th Ed.” which explains all you can, and cannot, do with packages in detail with code examples. It’s much better than trying to guess the syntax/semantics.

Again, package objects are totally irrelevant. In Scala, you can import any name, regardless of what it is. (Within some constraints – the compiler needs to be able to clearly understand what you mean.) Packages, classes, individual variables and functions – they’re all importable. Package objects are just a red herring, I suspect. (That’s why we’re asking what you’re trying to accomplish here.)

sorry for bothering you a lot. I carefully read that document and that chapter. but I am still not understanding the importing privilege. For example, here is a package and an object both called “bar”. the hierarchy is like below:

package foo{
  object bar{
    def dosomething():Unit={}
  }
  package bar{
    object apple{}
  }
  package object bar{
    def dosomething():Unit={}
  }
}

if I
import foo.bar

then what it imports? the package object or the object in the first layer?

I honestly have no idea – my recommendation would be “don’t do that”. The Scala Spec probably specifies some sort of priority order, but nobody reading the code will know, so I would very, very strongly say that you should avoid direct name conflicts like that.

(Also, putting that code into Scastie suggests that the name conflict is just plain illegal.)

1 Like

sorry for this wrong code. I have tried this code in the idea, it also told me the name conflict that the object bar conflicts with the package name bar.

but why I have this quesiton is that Java would not throw this error. Maybe just because Scala has the package object concept, so in a package, the subpackage’s name should not be the same as one of the class or trait or object and so on. but I didnot see this description in the document/book you mentioned above. Maybe I should check again.

thanks.

I can’t speak to Java – I just don’t know it that well – but again, I think you’re focusing way too much on package objects, which are an edge case and mostly irrelevant. (Especially in Scala 3.)

Seriously: while you’re learning the language, I recommend mostly ignoring package objects. They aren’t used much in normal code – they were introduced in Scala 2 to make certain usages more convenient, and they’re basically dead in Scala 3, since we don’t need them any more.

Java is a very different language: I think you’d have to ask Java folks why it works there. I believe it fails in Scala because you’re setting up ambiguity; I don’t know why Java would tolerate that.

1 Like

thanks for your advice.
Now in Scala, can I get an answer that the sub-package’s name and the class/object/trait’s name in the same parent package should not be the same?
I am not sure whether it’s because I am setting something wrong or just Scala designed so.
Cause I really did not see this description anywhere, So have to make sure. Java can not import just a package name like

import foo

so it has no ambiguity

That’s right:

package p {
  package q {
  }
  object q
}

is an error

6 |  object q
  |  ^
  |  q is already defined as package p.q

because packages are nested in Scala and are “modeled” as containers with members.

By contrast, Java packages are not logically nested: package a does not enclose package a.b.

One may say that a class may have a full name a.b.C where the prefix is its packaging and the suffix is its simple name. That is true for both Java and Scala. The package a.b exists because there are definitions with that packaging.

In Scala, you can import b.C, so binding b is significant.

I’m pretty sure all this is explained in the books. I remember the example with “Bob’s Rockets” from Programming in Scala. I don’t remember if that example was also used to talk about side effects, which often launchMissiles() for some reason.

1 Like

I have check that code example “Bob’s Rockets” again, that example shows how to package, but no description of class/objec/trait’s name collision with package’s name.

Ok, finally, by testing I know the rules. Thanks for all your help.