- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Question on fine-grained access modifiers
Tue, 2011-05-17, 22:36
I have the following bit of code:
/** A data structure containing all of the content of a document. */class Document {
/**We keep the details of data storage private to be able to restrict the ways in * which the rest of the code can access or manipulate the data */ private val model = new Object { private val contents = new ArrayBuffer[Node]
private def updateBackrefs = { for (i <- 0 until contents.length) contents(i).index = i }
private[Document] def insert(at: Int, node: Node) { contents.insert(at, node) updateBackrefs }
private[Document] def insert(at: Int, str: String) { for (c <- str.reverse) contents.insert(at, new Char(c.toString)) updateBackrefs } }...}
The val "model" is private within Document, but just in case a reference to it leaked out (perhaps via another method of Document), I wanted to make sure that its insert methods could not be called outside of Document, hence the "private[Document]" modifiers. However, this doesn't work; the insert methods are now no longer seen elsewhere in the Document class. In all fairness, I should mention that they get called in a method that is defined in an inner class of Document, eg.
class Document { ... class Position extends Marker { /**Insert a string either before or after this Position. * @param str The string to be inserted. * @param before True (the default) if the string is to be inserted before the * Position, false if the string is to be inserted after the Position. The default * cause corresponds to typing and expecting the Position (cursor) to end at the end * of the typed text. */ def insert(str: String, before: Boolean = true) { val index = if (before) this.index else this.index + 1 for (c <- str.reverse) model.insert(this.index, new Char(c.toString)) } }}
I can see access modifier rules getting pretty hairy in cases like this, but if anyone could provide some simple guidelines, I'd be grateful.
Thanks,Ken
/** A data structure containing all of the content of a document. */class Document {
/**We keep the details of data storage private to be able to restrict the ways in * which the rest of the code can access or manipulate the data */ private val model = new Object { private val contents = new ArrayBuffer[Node]
private def updateBackrefs = { for (i <- 0 until contents.length) contents(i).index = i }
private[Document] def insert(at: Int, node: Node) { contents.insert(at, node) updateBackrefs }
private[Document] def insert(at: Int, str: String) { for (c <- str.reverse) contents.insert(at, new Char(c.toString)) updateBackrefs } }...}
The val "model" is private within Document, but just in case a reference to it leaked out (perhaps via another method of Document), I wanted to make sure that its insert methods could not be called outside of Document, hence the "private[Document]" modifiers. However, this doesn't work; the insert methods are now no longer seen elsewhere in the Document class. In all fairness, I should mention that they get called in a method that is defined in an inner class of Document, eg.
class Document { ... class Position extends Marker { /**Insert a string either before or after this Position. * @param str The string to be inserted. * @param before True (the default) if the string is to be inserted before the * Position, false if the string is to be inserted after the Position. The default * cause corresponds to typing and expecting the Position (cursor) to end at the end * of the typed text. */ def insert(str: String, before: Boolean = true) { val index = if (before) this.index else this.index + 1 for (c <- str.reverse) model.insert(this.index, new Char(c.toString)) } }}
I can see access modifier rules getting pretty hairy in cases like this, but if anyone could provide some simple guidelines, I'd be grateful.
Thanks,Ken