Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala object private scope with inner classes and methods

I have a little confusion about accessing private inner classes of an object with the same object's methods. Here is the code of my excercise from Programming in Scala (pages 245-246):

import Element.elem

abstract class Element {
    def contents: Array[String]
    def height = contents.length
    def width = if(height == 0) 0 else contents(0).length

    def above(that: Element): Element = elem(this.contents ++ that.contents)

    def beside(that: Element): Element = {
    elem( for(
            (line1, line2) <- this.contents zip that.contents)
            yield line1 + line2 )
    }

    override def toString = contents mkString "\n"
 }


 object Element {

    private class ArrayElement (
            val contents: Array[String]
    ) extends Element

    private class LineElement (s: String) extends ArrayElement(Array(s)) {
            override def width = s.length
            override def height = 1
    }

    private class UniformElement (
            val ch: Character,
            override val width: Int,
            override val height: Int
    ) extends Element {
            private val line = ch.toString * width
            def contents = Array.fill(height)(line)
    }

    def elem(ss: Array[String]) = new ArrayElement(ss)
    def elem(s: String) = new LineElement(s)
    def elem(ch: Character, w: Int, h: Int) = new UniformElement(ch, w, h)

 }

The code is the same as in book, but the compiler complains about the three def elem() methods at the botton of the Element object. The error says:

private class ArrayElement escapes its defining scope as part of type pis.Code_c10s02_CompositionAndInheritance.Element.ArrayElement

however, if I remove the private modifier from the inner classes, everything becomes ok. This should not be the solution, seems this section of the book is essentially about privatizing classes inside an object. What is my mistake here?

like image 773
noncom Avatar asked Jan 05 '12 07:01

noncom


1 Answers

For some reason it would rather fail the compile than infer a less specific but public type. Declare the elem methods with return type.

def elem(ss: Array[String]): Element             = new ArrayElement(ss)
def elem(s: String): Element                     = new LineElement(s)
def elem(ch: Character, w: Int, h: Int): Element = new UniformElement(ch, w, h)
like image 59
psp Avatar answered Oct 18 '22 15:10

psp