In Rake, when you run a task explicitly from another task using the execute
command, ie:
Rake::Task['some_task'].execute(args=[arg1, arg2])
Inside the task that is run, the args
will be a regular Array. If you run a task with the invoke
function, ie:
Rake::Task['some_task'].invoke(arg1, arg2)
The args
command will be an instance of Rake::TaskArguments
. As such, you can use methods like Rake::TaskArguments.with_defaults
.
Why does this difference exist? Is there a way to ensure that the args inside a task will be an instance of Rake::TaskArguments
?
Generally, it seems odd that the method of calling a tasks changes the identity of the arguments.
Great question and I can't find a stated reason why invoke
wraps arguments as Rake::TaskArguments
and execute
doesn't.
execute
is called from invoke
in order to do the work of the task and at that point the arguments are already wrapped up into a Rake::TaskArguments
instance. That's why in "normal" usage you get a Rake::TaskArguments
within your task. I'd say normal usage is with tasks specified on the command line or as dependencies. In these cases you'd have the tasks being called via invoke
within rake itself.
To ensure that the arguments in the task are always a Rake::TaskArguments
instance I guess the only way is to wrap the arguments when you're using execute
in your own code. E.g.
Rake::Task['some_task'].execute(Rake::TaskArguments.new(argument_names, [arg1, arg2]))
argument_names
is required and is the names of the arguments the task expects. You can actually get that from the task itself Rake::Task['some_task'].arg_names
. The argument position in the name array needs to match the position in the value for named arguments.
Might be worth raising your question as an issue with the rake team : https://github.com/ruby/rake/issues