axeon
08/14/2024, 4:39 PMexecute function of a command. Below is a simplified version of my current setup:
abstract class Command {
abstract suspend fun ArgumentData.execute()
}
class Argument<T> {
lateinit var name: String
operator fun <T> getValue(thisRef: Any?, property: KProperty<*>) = this
}
// I've also tried to define `getValue` as an extension function but that does not help either
// operator fun <T> Argument<T>.getValue(thisRef: Any?, property: KProperty<*>): Argument<T> {
// return this
// }
class ArgumentData(map: Map<String, Any?>) {
inline operator fun <reified T> Argument<T>.getValue(thisRef: Any?, property: KProperty<*>): T {
return get<T>(name) // Retrieve the value from the map
}
}
Here's how it is supposed to be used:
command("example") { // this = ArgumentData
val exampleArgument: Argument<String> by argument()
execute {
println(exampleArgument)
}
}
The question is, how can I modify this code so that println(exampleArgument) outputs the value of the argument rather than the Argument class itself, in other words, use the extension function provided by ArgumentData instead? Is this behavior possible to achieve at all?
Thanks in advance!axeon
08/14/2024, 4:47 PMcoroutineContext from a non-suspending function. I could not find a way to store the context within the command either, as the command is instantiated only once and subsequent calls would simply overwrite the context of previous executions. Any suggestions?CLOVIS
08/14/2024, 4:58 PMCommand an interface.
> operator fun <T> getValue(thisRef: Any?, property: KProperty<*>) = this
The return value of this function is what gets printed. Currently, you put = this , so it always prints the Argument itself. If you put = name , it will print its name. You could put anything else.
Since this will change the type of the delegate value, your DSL will change a bit:
command("example") {
val exampleArgument: String by argument()
execute { … }
}
note how exampleArgument is declared as String (or whatever else you want returned when the variable is read) and not Argument<String> .axeon
08/14/2024, 5:16 PMaxeon
08/14/2024, 5:39 PMArgumentData from an Argument, where ArgumentData is unique to each command invocation, and Argument defined is per command. If only getValue were a suspending function, I could store a global coroutine context and retrieve the arguments based on the current invocation. These are the only two approaches I can think of to address this. Is this simply a limitation of the language atp?Youssef Shoaib [MOD]
08/14/2024, 5:40 PMgetValue from Argument completely. Instead, use the extension from ArgumentsData.axeon
08/14/2024, 5:45 PMArgumentsData is only available inside of execute, so I'd have to define the arguments there instead. But that way arguments aren't identified until first execution, and that has to happen before.CLOVIS
08/14/2024, 7:33 PMinvoke() operator on Argument , that's only available in the execute lambda.
You can see an example of this here: the prepared builder (similar to your argument) is available anywhere, but its value can only be accessed within test (your execute) by using the invoke operator.axeon
08/14/2024, 8:48 PMexecute, but I was hoping to find a way to delegate it directly. It seems that's not possible at the moment. Thanks for your help.asdf asdf
08/15/2024, 3:56 PMCLOVIS
08/15/2024, 5:15 PM