How about a "with" extension method to be like C# object initializer?


#1

You often run into the situation where you need to create an object and then call methods on it to set up the object because you cannot initialize all aspects in the constructor and the methods provided do not support chaining. Android Bundle is a good example of this. You would like to do it all in one expression without having to declare a variable to hold it and the repeating the variable name for each setter call.

C# has the concept of initializer blocks that are ideal for this situation (https://msdn.microsoft.com/en-us/library/bb397680.aspx). I am not suggesting that the language has to be hacked to support such a thing as I think it can all be done in stdlib.

The let method is nice in that you can declare a lambda expression as an extension method and you can call methods in the lambda where “this” is the target of the let method. I think we should also have a “with” extension method that behaves similarly but returns the target not some other variable.

So I think this might be a handy method in the stdlib:

public inline fun <T> T.with(f: T.() -> Unit): T {
    f()
    return this
}

so instead of having to do something like this:

.map {

val foo = Foo()

foo.someProperty = 1

foo.callSomeMethod(2)

foo
}

I can do this

.map {

Foo() with {

  someProperty = 1

  callSomeMethod(2)

}
}

Wouldn’t that be handy or is there something in stdlib that already does this? I suppose with one more line you could do it with the existing with:

.map {

with(Foo()) {

  someProperty = 1

  callSomeMethod(2)

  this

}
}


#2

Hi Dale,

It’s been added recently to the standard library as “apply”.

See: https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/util/Standard.kt#L29

So I guess it will be available in M13.

In a strange convergence, I added it to my own commons library a few days ago: https://github.com/andrewoma/kommon/commit/7746e76f22cc2b8359c28c0697bb6957abc8e1b0

Cheers,
Andrew


Spreadsheet for differences between let, with, run, apply and also
#3

Awesome!

For reference here is the ticket for it, marked as fixed in M13: https://youtrack.jetbrains.com/issue/KT-6903