doublemc
doublemc

Reputation: 3301

IntelliJ Scala worksheet - package names don't correspond to directories

I'm doing Martin Odersky's course on coursera.com and he has a class defined within a Scala Worksheet like this:

object intsets {
  println("Welcome to Scala WS")
}

abstract class IntSet {
  def incl(x: Int): IntSet
  def contains(x: Int): Boolean
}

And when I do it in my worksheet I get a warning: "Package names doesn't correspond to directories structure, this may cause problems with resolve to classes from this file". Project is freshly created using New Project -> Scala -> SBT. IntelliJ 2017.

Here is a screenshot: enter image description here

Upvotes: 1

Views: 995

Answers (1)

benvdh
benvdh

Reputation: 603

I'm taking the same course and same lesson.

Just did some fiddling. It seems IntelliJ has some problems with class and object definitions and packages when defined in worksheets.

I found two ways around this error. The first solves the issue above quickly:

  1. Don't wrap your runtime code inside an intsets object, but put it directly below the abstract class like so:

    abstract class IntSet {
      def incl(x: Int): IntSet
      def contains(x: Int): Boolean
      def union(other: IntSet): IntSet
    }
    
    println("Welcome to the Scala worksheet")
    

For the Lecture 3.2 video (when packages are introduced), you might encounter similar issues. There I resolved the issues by:

  1. Creating the week3 package under /src/main/scala
  2. Moving all classes and objects out of the scala worksheet into separate class and object files under the week3 package. Only the runtime code should remain in the scala worksheet file, and that file (despite being in the week3 package folder) does not have a package statement. It does import classes from that package, though. So in code:

    // week3/intsets.sc
    import week3.{Empty, NonEmpty}
    println("Welcome to the Scala worksheet")
    val t1 = new NonEmpty(3, Empty, Empty)
    val t2 = t1.incl(4)
    
    // week3/IntSet.scala    
    package week3
    
    abstract class IntSet {
      def incl(x: Int): IntSet
      def contains(x: Int): Boolean
      def union(other: IntSet): IntSet
    }
    
    // week3/Empty.scala
    package week3
    
    object Empty extends IntSet {
      def incl(x: Int) = new NonEmpty(x, Empty, Empty)
      def contains(x: Int) = false
    
      override def toString: String = "."
    
      def union(other: IntSet): IntSet = other
    }
    
    // week3/NonEmpty.scala
    package week3
    import week3.IntSet
    
    class NonEmpty(elem: Int, left: week3.IntSet, right: IntSet) extends IntSet {
      def incl(x: Int) =
        if(x < elem) new NonEmpty(elem, left.incl(x), right)
        else if(x > elem) new NonEmpty(elem, left, right.incl(x))
        else this
    
      def contains(x: Int) =
        if (x < elem) left.contains(x)
        else if (x > elem) right.contains(x)
        else true
    
      override def toString: String = "{" + left + elem + right + "}"
    
      def union(other: IntSet) =
        left.union(right).union(other).incl(elem)
    }
    

UPDATE: In case the above refactor gives build errors when running the worksheet. Run sbt clean compile from the terminal (source )

Upvotes: 1

Related Questions