This situation looks like a bug to me, but I’m new with Kotlin and really can’t tell.
I’m getting the following error:
Object ImportantConfigClass captures the script class instance. Try to use class or anonymous object instead
object ImportantConfigClass {
init {
DataClass().propExtension
}
}
data class DataClass (
val paused: Boolean = false
)
val DataClass.propExtension: Boolean
get() {
return this.paused
}
What does it mean that it captures the script class instance, and why does that happen?
0
This is because currently Kotlin scripts on the JVM works by putting everything in the script file into a single class, i.e. your code turns into something like this:
// The name of this class is automatically generated, but let's call this class 'Script' for now
class Script {
object ImportantConfigClass {
init {
DataClass().propExtension
}
}
data class DataClass (
val paused: Boolean = false
)
val DataClass.propExtension: Boolean
get() {
return this.paused
}
}
Now it should be clear as day why this doesn’t work. To call propExtension
, you not only need an instance of DataClass
as the extension receiver, you also need an instance of Script
as the dispatch receiver. But you do not have access to an instance of Script
in the object’s init
.
This is what the error means by “capture script class instance”. The “script class instance” refers to the instance of Script
that you need, to call propExtension
.
You might think, why doesn’t the compiler just generate some extra code to work around this? Well, it actually does, but not for object
s. If ImportantConfigClass
is a regular class
, this code works as expected. The compiler would simply change the class
to an inner class
, so it has access to the enclosing instance.
From KT-19423,
For objects and other singletons that capture the script instance
(e.g. by using a property from the script), the diagnostic is now
reported from the (IR) backend.The current JVM scripting implementation compiles scripts to classes,
and therefore the limitations are similar to what you’d get by
defining a class with a nested object. For capturing nested classes,
we are performing transformation to the inner classes. Unfortunately,
there is no such straightforward transformation for singletons.We may change something around it in the future, but for a moment this
is the scene used for scripting, so we have to live with the
limitations.
2