https://kotlinlang.org logo
#scripting
Title
# scripting
v

Vampire

05/31/2023, 3:32 PM
Why does
Copy code
data class Foo(val foo: Nothing? = null) {
    companion object {
        fun foo() {
            println(__FILE__)
        }
    }
}
fail compilation with
Copy code
error: object Companion captures the script class instance. Try to use class or anonymous object instead
and is there a way to mitigate it?
i

Ilya Muradyan

05/31/2023, 3:54 PM
In K1, you should imagine the script body as some class initializer. Properties you have inside the script are this class' properties, classes you have are this class' inner classes. So it's compiled to something like
Copy code
class C(val __FILE__: File) {
    inner data class Foo(val foo: Nothing? = null) {
        companion object {
            fun foo() {
                println(__FILE__)
            }
        }
    }
}
And of course you can't access class' properties from its companion (or its inner class companion). There is basically no way to mitigate this in K1 (unless you don't refer script properties from companion)
v

Vampire

05/31/2023, 3:57 PM
In the actual case I don't. There I call a function that uses
__FILE__
in the default value of a parameter of
Foo
and in the companion object I call that constructor, but that also counts as referring. 😞
I hoped
__FILE__
would be someway different and could be used anywhere in the file.
i

Ilya Muradyan

05/31/2023, 4:00 PM
Yes, that's because functions are also methods of the class, and you can't refer them in companion objects(
v

Vampire

05/31/2023, 4:01 PM
I don't, I call the constructor and its default value calls the function. But I'm nitpicking. 😄
😁 1
i

Ilya Muradyan

05/31/2023, 4:08 PM
So you basically can refer a property if you have an instance. And it even works with scripts. You can try if you wish...
Copy code
class Foo {
    companion object {
        fun foo(obj: Any) {
            val f = // obtain __FILE__ property of obj with reflection 
            println(f)
        }
    }
}


Foo.foo(this)
v

Vampire

05/31/2023, 4:17 PM
Nah, don't think so, but thanks. 😄
But still imho
__FILE__
should be special and available in the whole file.
You said with K1 this will not work. How will it be different with K2? Wouldn't the same limitation apply?
Ha, thank god you lied to me. 😄
Extension function / property ftw.
Copy code
data class Foo(val foo: Nothing? = null) {
    companion object
}

fun Foo.Companion.foo() {
    println(__FILE__)
}
i

ilya.chernikov

06/06/2023, 9:32 AM
Yes, the capturing of the script instance (which is needed to access the provided properties, and the
__FILE__
is just that) is limited by the language rules, in particular singletons cannot capture anything. The extension functions are not limited, of course. This limitation is arising on the translation to the JVM, and so far I don't see how we can overcome it in the K2 too, so probably it will remain a limitation at least in the initial K2 support. Theoretically, we can try to make
__FILE__
a special value that is not limited by these rules, but I'm not yet sure it is important enough to spend an effort on. Anyway, it would be helpful if you'll file an issue about
__FILE__
in YT.
v

Vampire

06/06/2023, 10:57 AM
37 Views