Make42 Make42 - 1 month ago 6
Scala Question

Make a variable globally readable, but only from the file writable

I want to have a

var
in a singleton object that I want to read from everywhere but only write into it from another singleton object (which is a companion object, but I don't think it matters here). Thus I put both objects into one file
MyClass
and made the
var
private but opened it up to the scope of the file with
private[MyClass]
.

As a toy example: Everything is in the same file "MyClass.scala":

object OtherObject {
private[MyClass] var myvar = 0.0
def variable = myvar
}
object MyClass{
def setmyvar(myvar: Double): Unit = {
OtherObject.myvar = 2.0
}
}
class MyClass { ... }


This does not work however. I get the error "MyClass is not an enclosing class". How can I do what I want to do?

Answer

This will be not a companion object. You can have companion of class and object, both sharing the same name. Thus the error.

Putting that aside, you can achieve that what you asked for, by having both objects in the same package and limiting access with private to that package, or wrapping those objects with another one, and setting appropriate private modifier, like here:

object MyWrapper {
    object MyObject {
        private[MyWrapper] var myvar = 0.0
        def variable = myvar
    }
    object MyClass{
        def setmyvar(myvar: Double): Unit = {
            MyObject.myvar = myvar
        }
    }
}

And then it works:

scala> MyWrapper.MyObject.variable
res3: Double = 0.0
scala> MyWrapper.MyClass.setmyvar(3)
scala> MyWrapper.MyObject.variable
res5: Double = 3.0

although it isn't especially elegant piece of code

Comments