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