Code snippet
command("somecommand"){
val name by StringArgument(this)
onExecute {
name //do whatever...
}
}
Context:
command{}
creates a Command
object, with a function literal with receiver as a parameter (init: Command.() -> Unit
). It is instantiated once on startup.
onExecute{}
adds an Execution.() -> Unit
lambda to a list of things to run, stored inside the Command, which creates an Execution
object whenever it is executed.
The reason I do this is to have access to common methods or parameters I want within the Execution without having to write onExecute{ execution -> ... }
do something like execution.doSomething() every time.
The StringArgument
is put into a list of arguments in the Command, and contains a map of Execution objects to values for the argument. I do this because the command recieves a String which it sends to StringArgument to parse and store before execution. It is specific to each Execution.
The problem:
operator fun getValue(thisRef: Any?, property: KProperty<*>)
requires a reference to the execution. It casts thisRef to Execution to have access to the arguments the execution was created with, and throws an error if it can’t.
Because the delegated property is accessed from the function literal with receiver, thisRef
is actually null, and not a reference to the receiver.
I understand why this happens, but I wonder if there is a specific reason the receiver couldn’t be passed into getValue?
I’ve given this much context to my problem because I’m wondering whether there is a better way to achieve what I want to. Sorry for the long read, and thanks in advance!
(Extra: A somewhat hacky fix to the problem that I’d like to avoid)
I could use extension functions in Command to make operator fun invoke()
and infix fun set(other)
to access the argument with name()
and name set "something"
. Does that sound too hacky?