4

In foo/bar/my_package/package.scala:

package foo.bar
package object my_package {
  type SomeType = java.lang.String
}

Then, in foo/bar/my_package/my_sub/MyClass.scala

package foo.bar.my_package.my_sub

class MyClass {
  var x: SomeType = _
}

This fails to compile; SomeType isn't found. If I change MyClass.scala to

package foo.bar.my_package
package my_sub

class MyClass {
  var x: SomeType = _
}

Everything works fine. What is the difference!?!??!

(This is Scala 2.8.1)

davetron5000
  • 24,123
  • 11
  • 70
  • 98

2 Answers2

5

Package declarations, like imports, give you access to everything inside them. So when you

package foo.bar.my_package

then you have everything available that you would if you did

import foo.bar.my_package._

Furthermore, declaring a package on a single line means that everything below belongs to that package:

package foo.bar.my_package {
  package my_sub {
    class MyClass { var x: SomeType = _ }
  }
}

(which is equivalent to:

package foo.bar.my_package
package my_sub
class MyClass { var x: SomeType = _ }

)

so you can see how the contents of foo.bar.my_package ought to be in scope in this case. In the other case, you only have the contents of foo.bar.my_package.my_sub available, which does not include SomeType.

davetron5000
  • 24,123
  • 11
  • 70
  • 98
Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • Note that in my second example, I'm not using curly braces for the package stuff; is this just implied? – davetron5000 Apr 22 '11 at 13:39
  • @davetron5000 It is not implied, it is just two different syntaxes for the very same thing. Rex is using curly braces to make it clear that `my_sub` is inside `foo.bar.my_package`. The important point, however, is that a `package` declaration imports everything at that point. – Daniel C. Sobral Apr 22 '11 at 16:42
  • Edited the answer to make that clear. I'll select this as the "right answer" if no one has a problem with my edit – davetron5000 Apr 25 '11 at 17:02
2

It's a visibility question.

package foo.bar.my_package.my_sub

class MyClass {
  var x: SomeType = _
}

When you declare x, the following things are visible:

  • Every member of MyClass
  • Everything inside foo.bar.my_package.my_sub
  • Every member of scala.Predef
  • Everything inside scala
  • Everything inside java.lang

The type SomeType is not inside any of those.

On the other hand, when you do:

package foo.bar.my_package
package my_sub

class MyClass {
  var x: SomeType = _
}

Then the visibility is:

  • Every member of MyClass
  • Everything inside foo.bar.my_package.my_sub
  • Everything inside foo.bar.my_package
  • Every member of scala.Predef
  • Everything inside scala
  • Everything inside java.lang

And SomeType is inside foo.bar.my_package, which is the second line.

A related question is why it works this way. You can get a start here, though there's a question precisely about that. I don't much like the answer to that question, though, as it really doesn't touch the reasons for it. It does link to a page on scala-lang about new features of Scala 2.8, in which Odersky explains the reasons.

Community
  • 1
  • 1
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681