Using the documented mixture of named and positional arguments (or args with default values for that matter), how to invoke a method without specifying any named param?
I'm trying to extend existing shared method without breaking everybody else's code, and this approach looked promising, but the following example fails:
def test(Map args, some, thing='default value'){
"$some $thing";
}
//good - adding any named parameter works
//test('yet', 'another good', anything:'notneeded');
//but not specifying named parameter fails
test('this', 'fails');
I was not able to find documentation about this behavior, and it looks strange.
Groovy collects all named parameters and puts them in a Map. The Map is passed on to the method as the first argument.
Named optional parameters You can call getHttpUrl with or without the third parameter. You must use the parameter name when calling the function. You can specify multiple named parameters for a function: getHttpUrl(String server, String path, {int port = 80, int numRetries = 3}) { // ... }
What are Optional Parameters? By definition, an Optional Parameter is a handy feature that enables programmers to pass less number of parameters to a function and assign a default value.
As the name suggests optional parameters are not compulsory parameters, they are optional. It helps to exclude arguments for some parameters. Or we can say in optional parameters, it is not necessary to pass all the parameters in the method. This concept is introduced in C# 4.0.
The groovy parser needs some information to work with in order to determine which method to execute.
So if you write:
test('yet', 'another good', anything:'notneeded')
This is translated into:
test([anything:'notneeded'], 'yet', 'another good')
i.e. all named parameter styled arguments (with the colon) are put into a map and placed at the start of the argument list. All remaining parameters are placed after that.
So Groovy now looks for a signature test(Map, String, String)
and correctly finds your method.
If there is no named parameter, this conversion does not happen and the signature would be test(String, String)
, which does not have a matching method.
So the solution is to create an additional method that matches the call without named parameters:
def test(some, thing='default value'){
test([:], some, thing)
}
That way, both named and not named calls are supported.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With