Reputation: 3
I am trying to make the construction of instances of a class depending on the scope in which they are defined without using explicit parameters.
This is part of a port from Python to Kotlin but the main idea would be something like:
var d = MyClass()
use_scope(contextAForScope) {
var a = MyClass()
use_scope(contextBForScope) {
var b=MyClass()
}
}
In this example the d
constructor would use a default context, a
constructor would use contextAForScope
and b
constructor would use contextBForScope
(use_scope is just a placeholder here).
Something like implicit contexts?
Of course, I could make the constructor parameter explicit but this will potentially be used many times in a single scope and I would prefer not to define an additional variable.
Upvotes: 0
Views: 2725
Reputation: 6148
class MyClass(val context: Int)
fun MyClass() = MyClass(0)
interface MyClassScope {
fun MyClass(): MyClass
}
object ContextAForScope : MyClassScope {
override fun MyClass() = MyClass(1)
}
object ContextBForScope : MyClassScope {
override fun MyClass() = MyClass(2)
}
inline fun useScope(scope: MyClassScope, block: MyClassScope.() -> Unit) {
scope.block()
}
fun main(args: Array<String>) {
val d = MyClass()
useScope(ContextAForScope) {
val a = MyClass()
useScope(ContextBForScope) {
val b = MyClass()
}
}
}
Use a factory function to create your class. If you name the function like the class, it looks like a constructor.
Define an interface with the same factory function and two objects for the scopes.
Define a function that takes the scope and the initializer block.
Now you can use the useScope
-Function and within the block the right factory function is invoked.
Upvotes: 1
Reputation: 29844
with
is what you are looking for:
class MyClass()
var d = MyClass()
fun main(args: Array<String>){
var c = "c: Could be any class"
var d = "d: Could be any class"
with(c) {
// c is "this"
var a = MyClass()
print(c) // prints "c: Could be any class"
with(d) {
// d is "this"
var b = MyClass()
}
// b is undefined in this scope
}
// a is undefined in this scope
}
with
takes a lambda as argument an everything in that lambda is only defined in that scope.
Upvotes: 0