Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

private field setter in scala

Tags:

scala

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!

like image 317
user747980 Avatar asked May 11 '11 04:05

user747980


1 Answers

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.)

like image 193
Rex Kerr Avatar answered Oct 26 '22 13:10

Rex Kerr