2017-12-15 8:02 GMT+01:00 Jochen Theodorou <blackd...@gmx.org>:

> On 15.12.2017 06:10, Nathan Harvey wrote:
>
>> I think your first step - "define a file that contains extension
>> functions" -
>> is slightly wrong. In Kotlin, you can place extension methods anywhere,
>> they
>> do not have to be confined to a single file (or worse, like Groovy, in a
>> totally different dependency). The syntax I discussed is what enables them
>> to do this.
>>
>
> I am aware of that you can define them anywhere. But frankly, I find that
> pretty messy. I mean defining quasi global extension methods randomly all
> over the place... does sound like maintenance hell to me. Probably best to
> declare them inline as well, then you will never ever be able to find them
> again, if they are from a library.


I disagree here. The fact that you can define extension methods locally in
Kotlin is a huge win, especially for DSLs. Unlike Groovy they are local, so
don't leak to other parts of the application. So you can define extensions
that will "enhance locally" something, and it's pure awesomeness. Take this
example:

class DecoratedTasks(val delegate: TaskContainer) : TaskContainer by
delegate {
    companion object {
        fun of(tasks: TaskContainer, block: DecoratedTasks.() -> Unit) =
            block(DecoratedTasks(tasks))
    }

    inline operator
    fun <reified T: Task> String.invoke(configuration: T.() -> Unit) =
        (getByName(this) as T?)?.run { configuration(this) }
}

fun TaskContainer.configure(block: DecoratedTasks.() -> Unit) =
DecoratedTasks.of(this, block)

which allows us to use this:

tasks.configure {
    "jar"<Jar> {
        archiveName = "foo"
    }
}

Note how the "String invoke" operator is overriden locally. It only makes
sense in this context, and everything is statically typed. I think it's a
huge win.

Reply via email to