2021年10月17日日曜日

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

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

GradleスクリプトはGroovyに基づいています(ここでは、Kotlinのことは忘れてください )、しかし、厳密にGroovyコードであるわけではありません。ここに、Gradleが密かに行なっていることの概要があります。

話題


About: Gradle
About: Groovy

この記事の目次


開始コンテキスト


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

ターゲットコンテキスト



  • 読者は、いかにGroovy Gradleスクリプトは本当にはGroovyスクリプトではないか、およびGradleが密かに行なっていることの概要を知る。

オリエンテーション


ここに、Gradleをフルに活用し始めることに向かう第1ステップがあります


本体

ト書き
Special-Student-7が、日本の、いくつかの山に囲まれた、古い、かなり孤立した家の、ある部屋にいる。


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


Special-Student-7-Hypothesizer
あのアンリーズナブルな「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の若干の基本


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

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

. . .そう、そうなる; より詳細には、それは、自動的に生成された'groovy.lang.Script'サブクラスに組み込まれる、Groovyのオフィシャルドキュメントに記されているとおり。

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

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

Special-Student-7-Rebutter
えーと、オフィシャルGroovyドキュメントはかなり良く書かれているようだ、例えば、Gradleのものと比較して。それは理解可能だ。


3: Gradleスクリプトの実態


Special-Student-7-Hypothesizer
しかしながら、そのメカニズムが働くようにするためには、勿論、いくつか手はずを整えておく必要がある、しかし、それがGradleスクリプトの中には見られない。具体的には、'methodMissing'メソッドが設置されていなければならない。

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

実際には、Gradleスクリプトは、自動生成される'org.gradle.groovy.scripts.BasicScript'サブクラスの中に組み込まれる('org.gradle.groovy.scripts.BasicScript'はGradleクラスであることに注意)。

Special-Student-7-Rebutter
ということは、Gradleスクリプトは、本当にはGroovyスクリプトではないのだ . . .

Special-Student-7-Hypothesizer
これでようやく推測できるのだが、'org.gradle.groovy.scripts.BasicScript'が、スクリプトクラス内で定義されていないプロパティまたはメソッドをプロジェクトインスタンスへ送り届ける役目を担っているのだ。

'org.gradle.groovy.scripts.BasicScript'が具体的にどのようにそうするかには私は踏み込まないが、Gradleスクリプトが、'org.gradle.groovy.scripts.BasicScript'サブクラス(それは、Groovyスタンダードの'groovy.lang.Script'クラスのサブクラスである)になり、そのサブクラスがスクリプト内で定義されていないプロパティまたはメソッドへのコールをプロジェクトインスタンスへ送り届けることは知っておかなければならない。

そのレベルのことはユーザーに明らかにすべきものだ、私の意見では。

Special-Student-7-Rebutter
同意する。Gradleオフィシャルドキュメントはその点をクリアにしないから、その話は意味をなさないのだ。それは理解できない、実際のところ。

Special-Student-7-Hypothesizer
私がGradleオフィシャルドキュメントに感じるのは、「君は理解する必要などない。」という、気分の悪くなるような上から見下ろした態度だ。私は理解する必要がある!


参考資料


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