自 Ant 1.8 起
在当前作用域中添加一个本地属性。属性作用域存在于 Apache Ant 的各个“块”级别。这些包括目标以及 并行 和 顺序 任务容器(包括 宏定义 主体)。给定作用域中的本地属性会“遮蔽”更高作用域中同名属性,包括全局作用域。请注意,在全局级别使用 Local 任务实际上会使属性对执行顶级操作的“匿名目标”变为本地属性;它不会为构建文件中的其他目标定义。
如果 <local> 任务在其定义之前,则属性将变为本地属性。请参阅示例部分。
| 属性 | 描述 | 必需 |
|---|---|---|
| name | 要在当前作用域中声明的属性 | 是 |
作为对 name 属性的替代(或与之结合),一个或多个嵌套 <name> 元素的嵌套文本指定要在本地作用域中声明的属性名称。自 Ant 1.10.13 起
<property name="foo" value="foo"/>
<target name="step1">
<echo>Before local: foo is ${foo}</echo>
<local name="foo"/>
<property name="foo" value="bar"/>
<echo>After local: foo is ${foo}</echo>
</target>
<target name="step2" depends="step1">
<echo>In step2: foo is ${foo}</echo>
</target>
输出
step1:
[echo] Before local: foo is foo
[echo] After local: foo is bar
step2:
[echo] In step2: foo is foo
这里 local 任务在目标 step1
的剩余部分中遮蔽了 foo 的全局定义。
<property name="foo" value="foo"/>
<parallel>
<echo>global 1: foo is ${foo}</echo>
<sequential>
<local name="foo"/>
<property name="foo" value="bar.1"/>
<echo>First sequential: foo is ${foo}</echo>
</sequential>
<sequential>
<sleep seconds="1"/>
<echo>global 2: foo is ${foo}</echo>
</sequential>
<sequential>
<local name="foo"/>
<property name="foo" value="bar.2"/>
<echo>Second sequential: foo is ${foo}</echo>
</sequential>
<echo>global 3: foo is ${foo}</echo>
</parallel>
输出类似于
[echo] global 3: foo is foo
[echo] global 1: foo is foo
[echo] First sequential: foo is bar.1
[echo] Second sequential: foo is bar.2
[echo] global 2: foo is foo
macrodef 中使用这可能是 local 最有用的应用场景。如果您在 Ant 1.8.0 之前需要在 macrodef 中使用“临时属性”,您必须尝试想出一个在宏调用之间唯一的属性名称。
假设您想编写一个宏来创建给定文件的父目录。一个简单的做法是
<macrodef name="makeparentdir">
<attribute name="file"/>
<sequential>
<dirname property="parent" file="@{file}"/>
<mkdir dir="${parent}"/>
</sequential>
</macrodef>
<makeparentdir file="some-dir/some-file"/>
但这会在第一次调用时创建一个全局属性 parent——由于属性不可变,任何后续调用都会看到相同的值,并尝试创建与第一次调用相同的目录。
在 Ant 1.8.0 之前,建议使用基于宏属性之一的属性名称,例如
<macrodef name="makeparentdir">
<attribute name="file"/>
<sequential>
<dirname property="parent.@{file}" file="@{file}"/>
<mkdir dir="${parent.@{file}}"/>
</sequential>
</macrodef>
现在,针对不同文件的调用将设置不同的属性,并且目录将被创建。不幸的是,这会“污染”全局属性空间。此外,在某些情况下,可能很难想出唯一的名称。
输入 <local>
<macrodef name="makeparentdir">
<attribute name="file"/>
<sequential>
<local name="parent"/>
<dirname property="parent" file="@{file}"/>
<mkdir dir="${parent}"/>
</sequential>
</macrodef>
每次调用都会获得一个名为 parent 的属性,并且根本不会存在任何全局属性。
@name 的单个调用更多 XML 行的补偿<local> <name>foo</name> <name>bar</name> <name>baz</name> </local>