https://kotlinlang.org logo
Title
w

wakingrufus

06/04/2020, 1:38 AM
I would just make a person function on the house object that constructs the Person and adds it, and not use an operator. I think the + operator makes sense if you are mutating a scalar value, like a number or appending to a string, but I think for collections a function is better, ESP if you are using a DSL marker to restrict scope, which makes discoverablity way better
👍 1
i

iguissouma

06/05/2020, 3:43 AM
Members on my team dont like the + operator too
b

Brady Aiello

06/06/2020, 6:40 PM
This is how I'd do it:
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
annotation class VillageMarker
    
data class Person(val name: String?, val age: Int?)
data class House(val members: List<Person>)
data class Village(val houses: List<House>)

@VillageMarker
class PersonBuilder() {
    var name: String? = null
    var age: Int? = null
    fun build(): Person {
        return Person(name, age)
    }
}

@VillageMarker
class HouseBuilder() {
    private val _members: MutableList<Person> = mutableListOf()

    fun person(block: PersonBuilder.() -> Unit) {
        _members.add(PersonBuilder().apply(block).build())
    }
    fun build(): House {
        return House(_members)
    }
}

@VillageMarker
class VillageBuilder() {
    private val _houses: MutableList<House> = mutableListOf()

    fun house(block: HouseBuilder.() -> Unit) {
        _houses.add(HouseBuilder().apply(block).build())
    }

    fun build(): Village {
        return Village(_houses)
    }
}

fun village(block: VillageBuilder.() -> Unit): Village {
    return VillageBuilder().apply(block).build()
}

val v = village {
    house {
        person {
            name = "Emily"
            age = 31
        }
        person {
            name = "Hannah"
            age = 27
        }
        person {
            name = "Alex"
            age = 21
        }
    }
}