區域

自 Ant 1.8 起

說明

將區域屬性新增至目前範圍。屬性範圍存在於 Apache Ant 的各種「區塊」層級。這些層級包括目標以及 平行順序 任務容器(包含 巨集定義 主體)。特定範圍的區域屬性會「遮蔽」較高層級的同名屬性,包括全域層級。請注意,在全域層級使用 Local 任務會有效地將屬性設定為在執行頂層作業的「匿名目標」中為區域屬性;它不會定義為建置檔案中的其他目標。

如果 <local> 任務先於屬性定義,則該屬性會成為區域屬性。請參閱範例區段。

參數

屬性 說明 必要
名稱 在目前範圍中宣告的屬性

指定為巢狀元素的參數

名稱

作為 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 之前的 Ant 中的 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>