Key realizations
satya - 7/18/2018, 8:07:06 AM
Gradle is an extreme exercise in closures
Gradle is an extreme exercise in closures
satya - 7/18/2018, 8:08:05 AM
Each closure may and likely have a different delegate
Each closure may and likely have a different delegate
satya - 7/18/2018, 8:31:24 AM
Sometimes symbols in script are shortcuts
//Take this for example
SomeTask {
//configure this task
}
//is a shortcut to
tasks.getByName("SomeTask", { closure }).
It just is!! No other explanation. In order to make it look like english!!
satya - 7/18/2018, 8:32:22 AM
This is an example where data became code!
This is an example where data became code!
satya - 7/18/2018, 9:14:10 AM
They seem to turn string arguments into method calls: Trojan Horse effect
They seem to turn string arguments into method calls: Trojan Horse effect
satya - 7/25/2018, 5:43:03 PM
Groovy API has three parts
1. Properties. Like any java object Groovy objects carry properties.
2. Methods.
3. Script blocks.
satya - 7/25/2018, 5:46:58 PM
More on Script Blocks
1. Imagine an object has a few properties that are themselves big, substantial objects.
2. To manipulate each of these objects, Groovy creates an additional method, (in parallel to that object property), that takes a script closure.
3. So these big objects and their respective closures go together. Inside that closure the big objects' properties and methods are available without referencing it. This is done by the parent object where it initializes that closure with a corresponding big object.
satya - 7/25/2018, 5:49:19 PM
Consider this
O1
O2
O2Script {}
O3
O3Script {}
//then you can do inside O1's script
O2Script {
//O2.a = b
a = b;
}
O3Script {
//O3.a = b
a=b
}
satya - 7/25/2018, 5:49:51 PM
You can discover script blocks by looking at the API docs for Groovy
You can discover script blocks by looking at the API docs for Groovy
satya - 7/25/2018, 5:55:06 PM
First Gradle Picture to understand
satya - 7/25/2018, 6:01:47 PM
How to read this picture
1. Gradle is a collection of objects (not classes) that are "set forth" when a build is run, and collaborate. So it is a collection of objects that are ready to go.
2. Gradle build script is a way to manipulate those objects. So the canvas is filled with objects. That is the starting point.
3. Each plugin may add new objects to that collection or color some of the existing objects.
4. An object has properties and methods
5. Some properties are bigger than others and represented as big objects
6. Each big object is paired with a script block (usually declared as a method that takes a closure). In the picture above the annotation (I) represents this pairing.
7. the number (1) (2) and (3) represent the many aspects of their parent object. Each of these objects are given their own script to manipulate their member variables and methods.
satya - 7/25/2018, 6:03:06 PM
Same thing represented as an object graph
satya - 7/25/2018, 6:04:44 PM
Here is how a couple of the Gradle specific objects shown that way
satya - 7/25/2018, 6:08:39 PM
So when someone says/sees a script block in gradle, it means
1. it is the piece of code that manipulates an object belonging to that script block
2. That code typically uses methods and properties of that script block object
satya - 7/25/2018, 6:09:18 PM
These script blocks are usually explicitly defined as methods on the parent object
These script blocks are usually explicitly defined as methods on the parent object
satya - 7/25/2018, 6:12:17 PM
Another way script blocks are possible
1. the extension mechanism of gradle allows a custom object to be added, as if it is a "big object"
2. This named extension property can carry with it a script block.
3. the "ext" is one of such built-in extension properties. this is why you will see the ext {} closure block
satya - 7/25/2018, 6:13:28 PM
Another script block exception is a named task
Named tasks can have their own script block
satya - 7/25/2018, 6:14:02 PM
And also explicit methods that take closure as one of their last arguments can have that closure as a script block
And also explicit methods that take closure as one of their last arguments can have that closure as a script block
satya - 7/25/2018, 6:20:45 PM
It is quite likely, (I don't know for sure)
1. That when an extension object is added as a property, the mechanism also adds a method with the same name but takes a closure as an argument.
2. the added method will know how to pass the corresponding property object as the delegate of that method
3. Same approach could have been taken when adding a task to the task list where that task becomes configurable through a closure at the project level.
satya - 7/27/2018, 1:34:24 PM
Script statements can be reinterpreted or translated to any method name of the delegate
1. when a "string" is encountered in script, the delegate is called assuming that string is a method call
2. the delegate can intercept that call and invoke a different method on its behalf
3. So "somename" can not only be seen as "getSomename()" bu also "get("somename")" or create("somename"), etc.
4. The actual delegate may not know this.
5. The owner that calls the closure can prepare a wrapper delegate that hides the real delegate and takes on the method invocation directly and in the process altering the meaning of method names and params!
6. This is how the configurations.some-name is translated configurations.create("some-name")
satya - 7/27/2018, 1:35:06 PM
See a broader discussion of this here: Understanding gradle Configurations