dino
dino

Reputation: 1133

Confusion with a simple Scala packaging example

I've been experiencing confusion over packaging classes in Scala and importing packages. Let me start with a pair of simple source files:

file: a/A.scala

package a

// Which of these imports should be used? They both seem to work.
//import a.b._
import b._

class A {
   val fieldB = new B
}

file: a/b/B.scala

package a.b

class B

usage

Compiling with scalac works without complaint with either of the imports above in A.scala

Trying to load these files in the REPL works differently:

$ scala
Welcome to Scala version 2.8.0.r0-b20100714201327 (Java HotSpot(TM) Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :l a/b/B.scala
Loading a/b/B.scala...
<console>:1: error: illegal start of definition
       package a.b
       ^
defined class B

scala> :l a/A.scala
Loading a/A.scala...
<console>:1: error: illegal start of definition
       package a
       ^
<console>:5: error: not found: value b
       import b._
              ^
defined class A

scala>

So, I have a some questions:

Thank you

PS I know the directory structure doesn't have to match the packaging. Doing so voluntarily is helping me to be less confused for now.

Upvotes: 2

Views: 3948

Answers (2)

Langley
Langley

Reputation: 497

To load your class from the console...

scala> :paste -raw io/hacking/yourpackage/YourClass.scala

If your class has a main you can then invoke it with:

scala> io.hacking.yourpackage/YourClass.main(Array())

Upvotes: 0

Moritz
Moritz

Reputation: 14212

First off you cannot define packages in the REPL. The reason for this is that your REPL-statements are actually wrapped into objects. That's why your :load command fails. You would need to compile your source files and add it to the classpath if you want to use packages.

When trying to resolve a symbol to be imported the compiler tries to find it in your actual scope, i.e. when you write

import a._
import b._

this will import everything from package a and everything from package a.b. If you are inside package a then b is in your scope already and the second import is sufficient. The compiler also initially imports scala._ so you can also use relative imports like import xml._ to import scala.xml._.

In addition there is a feature called nested packages which lets you write your B.scala like

package a
package b
class B { /* .... */ }

which results in everything from package a being imported in this file.

If the compiler cannot resolve an import to a relative symbol it will look in the default package (_root_).

Upvotes: 6

Related Questions