Gant 如何能够通过名称引用目标,并且不会出现丢失属性异常?

发布于 2024-08-21 10:47:12 字数 561 浏览 3 评论 0原文

在此处提供的代码中:Gant 文件,有以下代码:

target(dist: 'Create release artefacts') {
        depends(test)
        depends(jar)
}
target(run: 'Run the distributed jar') {
        depends(dist)
        Ant.java(jar: distributedJarPath, fork: 'true')
}

target(hello: 'Hello World') {
        println("Hello World")
}

setDefaultTarget(dist)

我对它的原理感兴趣能够编写 setDefaultTarget(dist),并且不会收到有关 dist 作为缺失属性的异常。此代码片段是否在某个对象的上下文中进行评估,并且目标创建实例变量?

In the code presented here: Gant file, there is the following code:

target(dist: 'Create release artefacts') {
        depends(test)
        depends(jar)
}
target(run: 'Run the distributed jar') {
        depends(dist)
        Ant.java(jar: distributedJarPath, fork: 'true')
}

target(hello: 'Hello World') {
        println("Hello World")
}

setDefaultTarget(dist)

I'm interested in how it's able to write setDefaultTarget(dist), and not receive an exception about dist as a missing property. Is this snippet evaluated in the context of some object, and the targets create instance variables?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月静好 2024-08-28 10:47:12

您需要考虑两项:脚本的绑定以及目标的声明方式。

首先是绑定。 Groovy 脚本与 Groovy/Java 类有点不同。 Groovy 脚本允许未绑定的变量。这意味着编译脚本时不需要声明变量。当编译器看到这些未声明的变量引用之一时,它会将对变量的引用转换为对 binding.getVariable(variable name) (或类似内容)的调用。因此,脚本的最后一行在功能上等同于

setDefaultTarget(binding.getVariable('dist'))

第二行,即目标的声明。当声明目标时,Groovy 编译器实际上会看到一个方法调用:target(Map args, Closureclosure)(或类似的方法)。当此方法执行时,它会检查参数,提取目标的名称,并在绑定中按该名称存储对闭包的一些包装引用。近似值是......

target(Map args, Closure closure) {
  binding.setVarialbe( 
    args.keySet().iterator().next(),
    gantClosureWrapping(args, closure))
}

当然,上面的代码是近似值,而不是真正的甘特代码。

所以本质上...

target(dist: 'doc') { ... }
// the above adds 'dist' as a variable to the binding

//...

setDefaultTarget(dist)
// dist is unbound, so it is replaced with binding.getVariable('dist')

There are two items you need to consider, the Binding of the script, and how a target is declared.

First there is the binding. A Groovy script is a bit different from a Groovy/Java class. Groovy scripts allow for unbound variables. Meaning when you compile the script the variable need not be declared. When the compiler sees one of these undeclared variable references, it will convert the refrence to the variable under the covers to a call to binding.getVariable(variable name) (or something thereabout). So the last line of the script is functionally equivilant to

setDefaultTarget(binding.getVariable('dist'))

Second there is the is the declaration of the target. When the target is declared the Groovy compiler is actually seeing a method call: target(Map args, Closure closure) (or thereabout). When this method executes it examines the args, extracts the name of the target, and stores some wrapped reference to the closure by that name in the binding. An appropximation would be..

target(Map args, Closure closure) {
  binding.setVarialbe( 
    args.keySet().iterator().next(),
    gantClosureWrapping(args, closure))
}

Of course the above code is an approximation and not the real gant code.

so in essence...

target(dist: 'doc') { ... }
// the above adds 'dist' as a variable to the binding

//...

setDefaultTarget(dist)
// dist is unbound, so it is replaced with binding.getVariable('dist')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文