Gradle:可変長引数も配列も受け取れるようにする

解決したいこと

gradleでメソッドを作る際に、可変長引数も配列も受け入れるようにしたい。例えば、

sample 'a', 'b'
sample ['a', 'b']

のいずれでも使えるようにしたい。なぜなら前者の場合はその場に記述しないといけないのだが、後者の場合はどこか別の場所で定義したり、プログラムで作成したりすることができるからである。例えば、

def A = ['a', 'b']
....
sample A

と書くことができる。以下のように記述するわけにはいかない。

def A = 'a', 'b'
...
sample A

解決策

以下のようにしてみた。


def expandVarArgs(Object args) { switch (args.length) { case 0: return [] case 1: if (args[0] instanceof List) return args[0].toArray() default: return args } } def sample(Object...args) { List list = expandVarArgs(args) println "start" list.each { println it } } def A = ['1', '2'] sample() sample '0' sample A sample '3', '4' sample(['5', '6']) //sample ['7', '8'] こうは書けないらしい

実行結果は以下になる

start
start
0
start
1
2
start
3
4
start
5
6

問題点

しかし、一つ問題がある。直接的に配列を書いた場合、

sample ['7', '8']

「Could not get unknown property ‘sample’ for root project ‘sample’ of type org.gradle.api.Project.」というエラーになってしまう。

これは未だになぜなのかわからない。特に上のような特殊な処理をしていなくとも。以下でエラーになる。

def foo(arg) {
}
foo ['7', '8']

配列を引数としてメソッドを呼び出しているだけなのだが、なぜこれがエラーなのか意味不明だ。ちなみに生のgroovyでも同じことをやってみたが、やはりエラーになってしまう。あちこちに「Groovy/Gradleで括弧が必要なのは、引数の無いときだけ」のように記述されているのだが、明らかに間違いのようだ。以下のように記述しないと動作しないからだ。

foo(['7', '8'])

一体どうなっているのだろうか?