|
- <!DOCTYPE html>
- <!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- <html lang="en">
-
- <head>
- <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
- <title>Local Task</title>
- </head>
-
- <body>
-
- <h2>Local</h2>
- <p><em>Since Ant 1.8</em></p>
- <h3>Description</h3>
- <p>Adds a local property to the current scope. Property scopes exist at Apache Ant's various "block"
- levels. These include targets as well as the <a href="parallel.html">Parallel</a>
- and <a href="sequential.html">Sequential</a> task containers
- (including <a href="macrodef.html">Macrodef</a> bodies). A local property at a given scope "shadows"
- properties of the same name at higher scopes, including the global scope. Note that using
- the <code>Local</code> task at the global level effectively makes the property local to the
- "anonymous target" in which top-level operations are carried out; it will not be defined for other
- targets in the buildfile.</p>
-
- <p>A property is made local if the <code><local></code> task precedes its definition. See the
- examples section.</p>
-
- <h3>Parameters</h3>
- <table class="attr">
- <tr>
- <th scope="col">Attribute</th>
- <th scope="col">Description</th>
- <th scope="col">Required</th>
- </tr>
- <tr>
- <td>name</td>
- <td>The property to declare in the current scope</td>
- <td>Yes</td>
- </tr>
- </table>
-
- <h3>Parameters specified as nested elements</h3>
- <h4>Name</h4>
- <p>As an alternative to (or in conjunction with) the <code>name</code> attribute, the nested text of
- each of one or more nested <code><name></code> elements specifies a property name to declare in
- the local scope. <em>Since Ant 1.10.13</em></p>
-
- <h3>Examples</h3>
-
- <h4>Temporarily shadow a global property's value</h4>
-
- <pre>
- <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></pre>
-
- <p>outputs</p>
-
- <pre class="output">
- step1:
- [echo] Before local: foo is foo
- [echo] After local: foo is bar
-
- step2:
- [echo] In step2: foo is foo</pre>
-
- <p>here the <code>local</code> task shadowed the global definition of <code>foo</code> for the
- remainder of the target <q>step1</q>.</p>
-
- <h4>Creating thread local properties</h4>
-
- <pre>
- <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></pre>
-
- <p>outputs something similar to</p>
-
- <pre class="output">
- [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</pre>
-
- <h4>Use inside <code>macrodef</code></h4>
-
- <p>This probably is where <code>local</code> can be applied in the most useful way. If you needed a
- "temporary property" inside a <code>macrodef</code> in Ant prior to Ant 1.8.0 you had to try to come
- up with a property name that would be unique across macro invocations.</p>
-
- <p>Say you wanted to write a macro that created the parent directory of a given file. A naive
- approach would be:</p>
-
- <pre>
- <macrodef name="makeparentdir">
- <attribute name="file"/>
- <sequential>
- <dirname property="parent" file="@{file}"/>
- <mkdir dir="${parent}"/>
- </sequential>
- </macrodef>
- <makeparentdir file="some-dir/some-file"/></pre>
-
- <p>but this would create a global property <code>parent</code> on the first invocation—and
- since properties are not mutable, any subsequent invocation will see the same value and try to
- create the same directory as the first invocation.</p>
-
- <p>The recommendation prior to Ant 1.8.0 was to use a property name based on one of the macro's
- attributes, like</p>
-
- <pre>
- <macrodef name="makeparentdir">
- <attribute name="file"/>
- <sequential>
- <dirname property="parent.@{file}" file="@{file}"/>
- <mkdir dir="${parent.@{file}}"/>
- </sequential>
- </macrodef></pre>
-
- <p>Now invocations for different files will set different properties and the directories will get
- created. Unfortunately this "pollutes" the global properties space. In addition, it may be hard to
- come up with unique names in some cases.</p>
-
- <p>Enter <code><local></code>:</p>
-
- <pre>
- <macrodef name="makeparentdir">
- <attribute name="file"/>
- <sequential>
- <local name="parent"/>
- <dirname property="parent" file="@{file}"/>
- <mkdir dir="${parent}"/>
- </sequential>
- </macrodef></pre>
-
- <p>Each invocation gets its own property named <code>parent</code> and there will be no global
- property of that name at all.</p>
-
- <h4>Use of nested name elements</h4>
- This style declares and executes a single task, as compensation for requiring more lines of XML than
- would individual invocations using <code>@name</code>:
- <pre>
- <local>
- <name>foo</name>
- <name>bar</name>
- <name>baz</name>
- </local>
- </pre>
- </body>
- </html>
|