Using Optional Method Arguments
Using optional, named method arguments on your helper functions can make your code easier to read and more self-documenting. For example, consider a global helper function queryRows() that simplifies common querying use cases.
Sometimes your calling code only requires a select list and a
from clause:
def rates = adf.util.queryRows(select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c')
where clause to filter the data and an
orderBy parameter to sort
it:def euroRates = adf.util.queryRows(select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c',
where: "FromCurrency = 'EUR'",
orderBy: 'ExchangeRate desc')By using
optional, named arguments, your calling code specifies only the information required and
clarifies the meaning of each argument. To adopt this approach, use a single parameter of
type Map when defining your
function:// Global Function
List queryRows(Map options)
queryRows() function is to explicitly pass
a Map as its single argument like
this:// Passing a literal Map as the first argument of queryRows()
def args = [select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c']
def rates = adf.util.queryRows(args)
You can also pass a literal Map inline without assigning it to a local
variable like this:
// Passing a literal Map inline as the first argument of queryRows()
def rates = adf.util.queryRows([select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c'])
Map directly inside the function call
argument list you can omit the square brackets. This makes the code easier to
read:// Passing a literal Map inline as the first argument of queryRows()
// In this case, Groovy allows removing the square brackets
def rates = adf.util.queryRows(select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c')
Map argument representing your function's optional parameters must be
first. If your function defines additional parameters, then when calling the
function, pass the values of the other parameters first followed by any optional,
named parameters you want to include. For example, consider the signature of following
findMatchingOccurrences() object function that returns the number of
strings in a list that match a search string. The function supports three optional
boolean parameters caseSensitive,
expandTokens,
useRegExp.Long findMatchingOccurrences(Map options, List stringsToSearch, String searchFor)
stringsToSearch and searchFor as shown
below:// Use an object function to count how many emails
// are from .org or .edu sites
def nonCommercial = findMatchingOccurrences(emails,'.*.org|.*.edu',
caseSensitive: true,
useRegExp: true)
Regardless of the approach the caller used to pass in the key/value pairs, your function
body works with optional, named arguments as entries in the leading Map
parameter. Be aware that if no optional argument is included, then the leading
Map parameter evaluates to null. So assume the
options parameter might be null and handle that case
appropriately.
queryRows() global function. Notice it
uses the safe-navigation operator (?.) when referencing the
select property of the options parameter just in case
it might be null and signals an error using another global function named
error().// Global Function: List queryRows( Map options )
// ---------------
// The options Map might be null if caller passes no named parameters
// so check uses the safe-navigation operator to gracefully handle the
// options == null case, too. We're assuming another global helper function
// named 'error()' exists to help throw exception messages.
if (!options?.select) {
adf.util.error("Must specify list of field names in 'select' parameter")
}
if (!options?.from) {
adf.util.error("Must specify object name in 'from' parameter")
}
// From here, we know that some options were supplied, so we do not
// need to continue using the "?." operator when using options.someName
def vo = newView(options.from)
// etc.