Larry Garfield
06/03/2024, 5:07 PMforeach (['a', 'b', 'c'] as $prop) {
print $obj->$prop . PHP_EOL;
}
But I don’t know what the Kotlin equivalent is.hho
06/03/2024, 5:08 PMLarry Garfield
06/03/2024, 5:09 PMLarry Garfield
06/03/2024, 5:09 PMhho
06/03/2024, 5:09 PMhho
06/03/2024, 5:10 PMhho
06/03/2024, 5:11 PMLarry Garfield
06/03/2024, 5:11 PMLarry Garfield
06/03/2024, 5:14 PMclass StoredPerson (
val id: UUID,
var name: String?,
var age: Int?,
)
class PersonUpdate (
val name: String?,
val age: Int?,
)
// Logic I want to simplify:
if (update.name != null) {
stored.name = update.name
}
if (update.age != null) {
stored.age = update.age
}
// Repeat for like 40 properties.
That’s a (very) simplified example of what I’m trying to do, in whatever approach involves the least amount of boilerplate typing.Larry Garfield
06/03/2024, 5:14 PMLarry Garfield
06/03/2024, 5:21 PMhho
06/03/2024, 5:32 PMephemient
06/03/2024, 5:39 PMclass Person(
var name: String?,
var age: Int?,
)
class PersonUpdate(
var name: String?,
var age: Int?,
)
fun Person.apply(update: PersonUpdate): Person = apply {
val personProperties = Person::class.memberProperties
.filterIsInstance<KMutableProperty1<Person, Any?>>()
.associateBy { it.name }
for (updateProperty in PersonUpdate::class.memberProperties) {
val personProperty = personProperties[updateProperty.name] ?: continue
val value = updateProperty.get(update) ?: continue
personProperty.set(this, value)
}
}
but in production I'd definitely either write the 40 lines or codegen them, instead of something "cleverer" like thatLarry Garfield
06/03/2024, 5:47 PMLarry Garfield
06/03/2024, 5:48 PMupdate.name?.let { name = it }
- OK, that’s much less bad than I was fearing. Not great, but not terrible.Michael de Kaste
06/04/2024, 11:37 AMLarry Garfield
06/04/2024, 2:04 PMLarry Garfield
06/04/2024, 2:04 PMupdate.name?.let { name = it}
approach and did it manually, which was acceptable, is only one line per field, and avoids messing with reflection.Joshua Hansen
06/04/2024, 5:04 PMPropertyDelegateProvider
whereby you'd store a reference to that property's name in some internal map. If you don't want to use reflection, it's still possible with some work.