I have some code that has the invariant that an object must be constructed in the function where it is ultimately used (for various reasons related to global state that aren’t ideal but are part of the assumption).
e.g. Suppose there is the function boo below that is responsible for manipulating moo.
def boo(mooGen: () => Moo) {
val m = mooGen() // a new MOO must be created HERE
m.moo()
}
Clients of boo that want to use boo must pass in a type of () => Moo, where the function generates the desired Moo.
Ideal client behavior:
boo( () => new Moo(// specific parameters here) )
The Moo is not created until inside the boo body.
However, a client can easily misstep with the following code:
val myMoo = new Moo(// specific parameters here)
boo( () => myMoo)
This breaks the invariant where we want the moo construction to occur only in boo.
So basically, I want to determine if the return value of mooGen is created within the call stack of the function or whether it was created beforehand.
There are many ways to verify this at runtime. However, is there any way to force this pattern at compile time? Using implicits or anything else clever?
Any ideas are appreciated!
Put boo and Moo into their own object, together with a Token class, that can’t be instantiated outside the object.
Now what you want can be done:
And what you don’t want can’t be done:
But if the client really wants to he can – unfortunately – still get his Moo: