Make42
Make42

Reputation: 13088

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?

Upvotes: 0

Views: 110

Answers (3)

michaJlS
michaJlS

Reputation: 2500

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 OtherObject {
        private[MyWrapper] var myvar = 0.0
        def variable = myvar
    }
    object MyClass{
        def setmyvar(myvar: Double): Unit = {
            OtherObject.myvar = myvar
        }
    }
}

And then it works:

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

although it isn't especially elegant piece of code

Upvotes: 2

Alexey Romanov
Alexey Romanov

Reputation: 170735

but opened it up to the scope of the file

A file doesn't define a scope in Scala, period. So you can't make something writable only within the same file.

(There are actually three cases where files are relevant to scope that I can think of:

  1. Top-level package statements have the rest of the entire file as their scope.

  2. A class and an object with the same name are only companions if they are in the same file.

  3. sealed traits or classes can only be extended in the same file.

None of them are useful for your question.)

Upvotes: 1

Balaji Reddy
Balaji Reddy

Reputation: 5700

A companion object must be defined inside the same source file as the class. Both should have same name. one should be class and another should be object type. Then only we can call it as companion.

object MyClass {
    private[MyClass] var myvar = 0.0
    def variable = myvar
}
class MyClass{
    def setmyvar(myvar: Double): Unit = {
        // your logic 
    }
}

http://daily-scala.blogspot.in/2009/09/companion-object.html

Upvotes: 0

Related Questions