web-dev-qa-db-ja.com

gradleファイル内のextとコードブロックの意味

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

上記のコードはbuild.gradleのスニペットです

{}クロージャーパラメーターでextメソッドを呼び出すことを理解しています。それはそうです?だから私はgradleがspringVersionとemailNotificationにアクセスしていると思います。以下のコードで仮定を検証します

def ext(data) {
    println data.springVersion
}

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

ただし、以下のコードを実行するとエラーが発生しました。

groovy.lang.MissingPropertyException: No such property: springVersion for class: Test

extとコードブロックを具体的に説明していますか?

38
uuidcode

extproject.extの省略形であり、projectオブジェクトの追加のプロパティを定義するために使用されます。 (他の多くのオブジェクトに追加のプロパティを定義することもできます。)追加のプロパティを読み取る場合、ext.は省略されます(例:println project.springVersionまたはprintln springVersion)。メソッド内からも同じことができます。 extという名前のメソッドを宣言することは意味がありません。

61

問題のサンプルコードがエラーを生成する理由の説明を次に示します。

コード内:

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

SpringVersionおよびemailNotificationプロパティを持つオブジェクトを関数 "ext"に渡しません。中括弧は、POJOではなくクロージャーを意味します。これが、「ext」関数がプロパティに到達できないと文句を言う理由です。

構成クロージャーとして知られているこのようなクロージャーを渡すアイデアは、受信機能が以下を行うことです。

  1. クロージャーのデリゲートプロパティを変更して、クロージャーのプロパティ/メソッドが動作するオブジェクトを指すようにします。

  2. closure()を実行します

したがって、クロージャが実行され、メソッド/プロパティを参照すると、これらは設定されるオブジェクトで実行されます。

したがって、コードに次の変更を加えると機能します。

class DataObject {
   String springVersion;
   String emailNotification;
}

def ext(closure) {  
    def data = new DataObject() // This is the object to configure.
    closure.delegate = data;
    // need this resolve strategy for properties or they just get
    // created in the closure instead of being delegated to the object
    // to be configured. For methods you don't need this as the default
    // strategy is usually fine.
    closure.resolveStrategy = Closure.DELEGATE_FIRST 
    closure() // execute the configuration closure
    println data.springVersion
}

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

これが役立つことを願っています。 Groovyクロージャーは、慣れるまでに時間がかかります...

7
Ronen

ExtraPropertiesExtensionによるget()およびset()のオーバーライドが、これまで定義されていなかったプロパティが機能するための構成構文を作成するための鍵です。

class DataObject {
    HashMap<String, Object> props = new HashMap<String, Object>()

    Object get(String name) {
        return props.get(name)
    }

    void set(String name, @Nullable Object value) {
        props.put(name, value)
    }
}

def myExtInstance = new DataObject()

def myExt = { Closure closure ->
    def data = myExtInstance
    closure.delegate = data;
    // need this resolve strategy for properties or they just get
    // created in the closure instead of being delegated to the object
    // to be configured. For methods you don't need this as the default
    // strategy is usually fine.
    closure.resolveStrategy = Closure.DELEGATE_FIRST
    closure() // execute the configuration closure
    println data.springVersion
}

myExt {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

println "myExtInstance.springVersion" + myExtInstance.springVersion

ExtraPropertiesExtension docs を参照してください

1
enl8enmentnow