2021年1月17日日曜日

2: GradleスクリプトをGroovyコードとして道理付けようと試みる

<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>

GradleスクリプトはGroovyに基づいています(ここでは、Kotlinのことは忘れてください )、しかし、本当にはGroovyコードとして意味をなしません。

話題


About: Gradle

この記事の目次


開始コンテキスト


  • 読者は、GroovyまたはJavaの基本的知識を持っている。

ターゲットコンテキスト



  • 読者は、いかに、GradleスクリプトはGroovyに基づいているが、本当にはGroovyスクリプトでないことを知る。

オリエンテーション


あなたがGradleをフルに活用しはじめるためにオフィシャルドキュメントは協力的でないと認めることは有益だろう。

より適切な第1ステップが助けになるだろう。


本体


1: あのアンリーズナブルな「Hello World」スクリプトをGroovyコードとしてもっとリーズナブルであるように私は是正した、しかし、それでも、それは道理に合わない. . .


Hypothesizer 7
あのアンリーズナブルな「Hello World」スクリプトを、前記事にて、もっとリーズナブルであるように、私は是正した。

@Gradle ソースコード
task ("hello", {
	doLast ({
		println ('Hello world!')
	})
})

しかし、それでも、それは道理に合わない. . .

'task'は、ファンクションであって、'org.gradle.api.Project'インターフェイス(実際には、'org.gradle.api.internal.project.DefaultProject'、等によって実装されている)のメソッドであるようだ、どうやら。

しかしながら、そのスクリプト内の、その、修飾されていない'task'コールは、いかにして、当該プロジェクトインスタンスへ届けられるのか?そのスクリプトは、本当は、当該プロジェクトクラス内にて動作するのか?. . .いいや、それは、ある'groovy.lang.Script'サブクラス内で動作する。

一体、そこでは何が起きているのか?えーと、それを理解するためには、Groovyの基本をある程度学ぶ必要がある。


2: Groovyの若干の基本


Hypothesizer 7
そもそも、Groovyスクリプトは、いかにして実行されるに至るのか?

GroovyはJavaに基づいていますよね?私が理解する限り、ロジックがクラスの外にあることをJavaは許さないので、スクリプトは、あるJavaクラスへ組み込まれるのか、多分?

. . .そう、そうなる; より詳細には、それは、自動的に生成された'groovy.lang.Script'サブクラスに組み込まれる、Groovyのオフィシャルドキュメントに記されているとおり(余談だが、オフィシャルGroovyドキュメントは、かなりよく書かれているように見える、例えば、Gradleのものと比較して)。

メインロジックは当該'groovy.lang.Script''run'メソッドの中へ行くが、スクリプトコード全体がその'run'メソッドの中へそのまま行くというほど、ことは単純ではない。それは、'import'指令やファンクション定義といった一部のステートメントは、メソッドの中には行けないからだ、Java的に言って。

留意すべき重要なある事実は、Groovyメソッドコールは、単純なJavaメソッドコールにはならないことであり、それが、Groovyにおいて、「ダイナミックメソッド」機能が可能である理由だ。. . .したがって、Groovyは実際に、存在しないメソッドがコールされたり存在しないプロパティがアクセスされたりすることを許すメカニズムを持っている。


3: Gradleスクリプトの実際


Hypothesizer 7
しかしながら、そのメカニズムが発動されるためには、勿論、一定の手はずが行なわれ済みであることが要求されるのだが、それがGradleスクリプトの中に見られない。具体的には、'methodMissing'メソッドが準備されていなければならない。

実は、Gradleスクリプトは、プリプロセスされた後でさえ、Groovyに渡されない。

それはどういう意味なのか?えーと、Gradleスクリプトは、自動的に生成された'org.gradle.groovy.scripts.BasicScript'サブクラスの中に組み込まれる('org.gradle.groovy.scripts.BasicScript'は、Gradleのクラスであることに注目しよう)。

これで推測できるのは、'org.gradle.groovy.scripts.BasicScript'が、スクリプトクラス内で定義されていないプロパティやメソッドのコールを当該プロジェクトインスタンスへ届ける任務を担っているということだ。

'org.gradle.groovy.scripts.BasicScript'がどう具体的にそうするのかを掘り下げるのはやめるが、Gradleスクリプトが'org.gradle.groovy.scripts.BasicScript'サブクラス(それは、Groovyスタンダードの'groovy.lang.Script'クラスのサブクラスである)になり、そのサブクラスが、その中で定義されていないプロパティやメソッドのコールを当該プロジェクトインスタンスへ届けるのであること、を私は知っておく必要がある。

そのレベルの説明はユーザーに対してするべきだ、私の意見では。


参考資料


<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>