is there some elegant way in Kotlin to allow some ...
# announcements
m
is there some elegant way in Kotlin to allow some syntax like the following one?
Copy code
class Asdf private constructor() {
    companion object {
        operator fun invoke(s: Asdf.() -> Unit) {
            this.s() // doesn't make sense, Asdf().s() would work instead
        }
    }
}

// to be called as follows:
Asdf { }
this doesn't work because there's no
this
in a companion object. I guess I could have a lazy property to an
Asdf
instance, but can I have no instance at all?
r
this
in an object (including a companion object) refers to the object
m
mmm
alright, but
this.s()
gives me public abstract operator fun Asdf.invoke(): Unit defined in kotlin.Function1
I assume it's not the class itself
r
if you want the invoke syntax, use
Copy code
object X {
     operator fun invoke(s: Receiver.() -> Unit) { /* actually do something */ }
}

// permits:
X {}
m
oh that's nice. Thanks for the help
I was trying something longer but I just noticed I was doing something conceptually wrong
a
Copy code
class Asdf private constructor() {
    companion object {
        operator fun invoke(s: Asdf.() -> Unit): Asdf =
            Asdf().apply(s)
    }
}
// to be called as follows:
Asdf { }
? It instantiates a new Asdf, and applies the block, then returns the instance.
👍 1
m
that's neat too. I'm just experimenting, I'm not doing anything practical :^) It helped me notice I was thinking of the companion object and the class as one thing, so that was giving me problems. Thanks for the suggestions
Copy code
class Manu private constructor() {
    companion object Saurio {
        val sing: Unit
            get() = println("Whether you're a brother or whether you're a mother you're stayin' alive, stayin' alive")
        
        operator fun invoke(lambda: Saurio.() -> Unit) {
            this.lambda()
        }
    }
}

fun main() = Manu {
    sing
}
the features this language has make me very curious
😜 1
K 1
t
These are all the basics behind the various Kotlin DSL libraries. And it’s truly fantastic, the best out of a large set of amazing features 😄
y
You can also do:
Copy code
class Asdf private constructor() {
    companion object {
        operator fun invoke(s: Asdf.() -> Unit) {
            s(Asdf())
        }
    }
}

// to be called as follows:
Asdf { }
that's because an extension function is considered a function with the first parameter being the extension receiver
👍 1