0

I have a class with some attributes:

class DonutBox {
    var glaze: Int = 0
    var chocolate: Int = 0
    var maple: Int = 0
    var etc: Int = 0
}

fun addDonuts() {
    val omNom = DonutBox()
}

How can I increment a random attribute of the instantiated class?

For instance, if the randomly selected attribute is chocolate, then effectively:

omNom.chocolate += 1

1 Answer 1

3

Because Kotlin's properties are statically declared, and you want to use them dynamically, most of the methods to do that will involve reflection, which can get pretty messy and difficult to understand.

When you want dynamic data, it's probably better to use a map:

val donutBox = mutableMapOf(
    "glaze" to 0,
    "chocolate" to 0,
    "maple" to 0,
    "etc" to 0,
)

val randomKey = donutBox.keys.random()
donutBox[randomKey] = donutBox.getValue(randomKey) + 1

println(donutBox)

Output:

{glaze=0, chocolate=0, maple=1, etc=0}

That said, if you really want to use reflection, you can do it like this:

data class DonutBox(
    var glaze: Int = 0,
    var chocolate: Int = 0,
    var maple: Int = 0,
    var etc: Int = 0,
)

fun addDonuts() {
    val omNom = DonutBox()
    val randomProperty = omNom::class.declaredMemberProperties.random() as KMutableProperty1<DonutBox, Int>
    val existing = randomProperty.get(omNom)
    randomProperty.set(omNom, existing + 1)
    println(omNom)
}

fun main() {
    addDonuts()
    addDonuts()
    addDonuts()
}

Output:

DonutBox(glaze=0, chocolate=1, maple=0, etc=0)
DonutBox(glaze=0, chocolate=0, maple=0, etc=1)
DonutBox(glaze=0, chocolate=1, maple=0, etc=0)
Sign up to request clarification or add additional context in comments.

1 Comment

In addition to being long-winded and ugly, reflection tends to be slow, unsafe (risking runtime errors that can't be spotted at compile-time), insecure, and isn't available on the most limited platforms.  There are times when you genuinely need it — but more often (like here), it's a code smell, indicating that the design could be improved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.