what is the best way to have a class field in scala be read-only outside of the class? i realize i can do something like this:
private var myvalX = 0 // default val
def myval = myvalX
def myval_=(x: Int) { myvalX = x }
but i find it extremely ugly due to the _= operator and the fact that you need to define a separate var whose name is different than the methods. alternatives would be very welcome. thank you!
I don't think it's good practice to have private fields and public ones share the same name. For example, you wrote
private var myvalX = 0 // default val
def myval = myvalX
def myval_=(x: Int) { myvalX = x }
which doesn't make myval
read-only at all! You probably meant something like
private def myval_=(x: Int) { myvalX = x }
which would be read-only. But this is a perfect example of why it's a bad idea--you are asking for confusion between a public interface and your private implementation details. Other problems that can arise are users not realizing that the value might change out from under them, subclasses redefining the public getter without realizing that the private setter is not available, and so on.
If you don't try to share the name, then it's clearer that there are two things to think about: your underlying data, and the public interface that relies upon that data.
private var myData = 0
def data = myData
That's not so bad, is it?
Alternatively, you can use various tricks to make things look somewhat nicer if you really insist on using this pattern. For example, if you have a bunch of fields you could
class C {
abstract class ReadOnly[A] { def value: A }
private class ReadWrite[A](var value: A) extends ReadOnly[A]
private implicit def access[A](ro: ReadOnly[A]) = ro.asInstanceOf[ReadWrite[A]]
def rw[A](a: A): ReadOnly[A] = new ReadWrite(a)
val data = rw(0)
val comment = rw("Ho-hum")
}
which will let anything in class C set data.value
and comment.value
, and only let everyone else read them. (Edit: modified to include all the goodies in the original example, since if you omit them you might make errors.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With