オプションのメソッド引数の使用
ヘルパー関数でオプションの名前付きメソッド引数を使用すると、コードを読みやすくしたり、自己文書化したりできます。 たとえば、一般的な問合せのユースケースを簡略化するグローバル・ヘルパー関数queryRows()を考えてみます。
コール・コードでは、select
リストとfrom
句のみが必要な場合があります:
def rates = adf.util.queryRows(select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c')
場合によっては、データをフィルタ処理するために
where
句が必要になり、ソートするためにorderBy
パラメータが必要になることがあります:def euroRates = adf.util.queryRows(select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c',
where: "FromCurrency = 'EUR'",
orderBy: 'ExchangeRate desc')
オプションの名前付き引数を使用すると、コール・コードで必要な情報のみが指定され、各引数の意味が明確になります。 このアプローチを採用するには、関数を定義するときにMap
型の単一パラメータを使用します: // Global Function
List queryRows(Map options)
もちろん、
queryRows()
関数を呼び出す1つの方法は、次のような単一の引数としてMap
を明示的に渡すことです:// 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)
リテラルMap
を次のようにローカル変数に割り当てずにインラインで渡すこともできます:
// Passing a literal Map inline as the first argument of queryRows()
def rates = adf.util.queryRows([select: 'FromCurrency,ToCurrency,ExchangeRate',
from: 'DailyRates_c'])
ただし、関数コールの引数リスト内でリテラル
Map
を直接渡す場合は、大カッコを省略できます。 これにより、コードが読みやすくなります: // 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
引数が先頭である必要があります。 ファンクションで「追加」パラメータを定義する場合、ファンクションをコールするときに、他のパラメータの値を最初に「後に続く」、含めるオプションの名前付きパラメータを渡します。 たとえば、検索文字列に一致するリスト内の文字列の数を返す次のfindMatchingOccurrences()
オブジェクト関数のシグネチャについて考えてみます。 このファンクションでは、3つのオプションのboolean
パラメータcaseSensitive
, expandTokens
, useRegExp
がサポートされています。 Long findMatchingOccurrences(Map options, List stringsToSearch, String searchFor)
コードの呼出しは、次に示すように、
stringsToSearch
およびsearchFor
の値の後にオプションの名前付き引数を渡します:// 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)
キー/バリューのペアを渡すためにコール元が使用した方法に関係なく、関数本文は、先頭のMap
パラメータのエントリとして、オプションの名前付き引数を使用します。 オプションの引数が含まれていない場合、先頭のMap
パラメータはnull
と評価されることに注意してください。 そのため、options
パラメータがnull
である可能性があり、そのケースを適切に処理するとします。
コードでは、着信オプション引数を検証し、必要に応じて、呼び出し元が明示的に渡さなかったオプションのデフォルト値を指定します。 次の例は、
queryRows()
グローバル関数のコードの開始行を示しています。 options
パラメータのselect
プロパティを参照するときに、null
であり、error()
という名前の別のグローバル関数を使用してエラーを通知する場合にのみ、safe-navigation演算子(?.
)が使用されます。 // 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.