Menu

Why does ForEach for tasks instead of targets

Help
2004-03-30
2004-05-06
  • William Shubert

    William Shubert - 2004-03-30

    I have a general question. I'm using ForEach, and it works,  but it seems clumsy because of the way that it requires a target. Is there a reason that it doesn't work more like, for example, the "if" task, so that I can just put tasks in it?

    For example, I'd like:

    <!-- Get an up to date copy of all files -->
    <foreach param="file"">
      <path>
        <fileset dir="cachedFiles"/>
      </path>
      <tasks>
        <get src="http://sourceHost/${file}" dest="${file}"/>
      </tasks>
    </foreach>

    It seems like foreach actually creates a sub-version of ant for each iteration, which makes a simple loop like this quite slow. Is this all necessary because of ant's insistence that properties are global and unchangeable? And, is there a way to improve the current foreach so that it will be simpler and faster?

    Thanks.

     
    • Matt Inger

      Matt Inger - 2004-05-06

      It's a limitation of the way earlier versions of ANT work.  If you were to do the following:

      <foreach list="a,b,c" param="letter">
         <echo message="${letter}" />
      </foreach>

      when the "foreach" task instance is created (not evaulated), so is the <echo> task underneath, and the ${letter} is evaluated at that time.  Thus, there is no parameterization, and ${letter} would not even be set to anything.  so you'd end put with the following output:

      [echo] ${letter}
      [echo] ${letter}
      [echo] ${letter}

      There is no workaround for this in earlier versions of ant.  However, in ANT 1.6, the MacroDef facility allows us a way to do it.  But to maintain backward compatibility, we created a seperate task for it:

      <for list="a,b,c" param="letter">
        <sequential>
           <echo>Letter @{letter}</echo>
        </sequential>
      </for>

      The taskd are created as a MacroDef instance, and as a result @{letter} is evaluated when the macro itself is evaluated.  So each time through the loop, we can set the macro parameter, and evaluate the macro, thus producing the correct results.

       

Log in to post a comment.