I'm trying out code in section 10.12, namely adding a new method called "above" to the class Element. Running this in REPL, it gives me the following compile error:
<console>:14: error: type mismatch; found : ArrayElement required: Element new ArrayElement(this.contents ++ that.contents) ^
However, if I move this method into class "ArrayElement" instead, it works fine. I suspect it has something to do with class Element not being aware of existence of ArrayElement. Here is the source code:
abstract class Element { def contents: Array[String] def height: Int = contents.length def width: Int = if (height == 0) 0 else contents(0).length
def above(that: Element): Element = new ArrayElement(this.contents ++ that.contents) // ERROR HERE }
class ArrayElement( val contents: Array[String] ) extends Element
I know that later in the text the code gets refactored and "above" is moved into a companion object, but the fact that this intermediate version doesn't compile is a bit misleading to the reader.
What is the right version of the source code?
Besides this little glitch, I'm highly enjoying the book so far.
The compiler compiles whole files, whereas the REPL compiles top level expressions as it sees them. When it sees new ArrayElement(...), it hasn't yet seen its definition so it doesn't know that it's a subclass of Element. If you're going to hand code fragments to the REPL, you have to get the order right, or you have to include them inside a single top level construct. e.g.,
scala> scala> class Element defined class Element
scala> val a: Element = new ArrayElement <console>:6: error: not found: type ArrayElement val a: Element = new ArrayElement ^
scala> class ArrayElement extends Element defined class ArrayElement
but
scala> object Foo { | class Element | val a: Element = new ArrayElement | class ArrayElement extends Element | } defined module Foo