Can I define method-private fields in Scala?

Given this situation:

object ResourceManager { private var inited = false def init(config: Config) { if (inited) throw new IllegalStateException // do initialization inited = true } } 

Is there any way to make inited somehow β€œprivate” for init () "so that I can be sure that no other method in this class can ever set inited = false ?

+3
source share
4 answers

Taken from Scala, how would you declare static data inside a function? . Do not use a method, but a function object:

 val init = { // or lazy val var inited = false (config: Config) => { if (inited) throw new IllegalStateException inited = true } } 

During the initialization of the outer region (in the case of val ) or the first access ( lazy val ), the body of the variable is executed. Thus, inited set to false . The last expression is an anonymous function, which is then assigned to init . Then, each subsequent access to init performs this anonymous function.

Note that it does not behave exactly like a method. That is, it is quite fair to call it without arguments. Then it will behave like a method with a final underscore method _ , which means that it will simply return an anonymous function without complaints.

If for some reason you really need the behavior of the method, you can make it private val _init = ... and call it from the public def init(config: Config) = _init(config) .

+6
source

This is understood as the more problems that it faces, but satisfies the specifications. There is no way to do it differently

 object ResourceManager { private object foo { var inited = false def doInit(config:Config){ if (inited) throw new IllegalStateException // do initialization inited = true } } def inner(config: Config) { foo.doInit(config) } } 
+5
source

It would be easier to create a trapdoor object that can only go from false to true:

 object ResourceManager { object inited { private var done = false def apply() = done def set = done = true } def init(config: Int) { if (inited()) throw new IllegalStateException // do initialization inited.set } } 
0
source

If all you want to do is make sure init is called once, do something like this:

 lazy val inited = { // do the initialization true } def init = inited 

thus, the initialization code will be executed only once, however many times you run init , and inited cannot get another value, since it is val . The only drawback is that as soon as inited requested for its value, initialization will work ...

0
source

All Articles