----- Original Message ----- 
From: "Troy Laurin" <[EMAIL PROTECTED]>
To: "Alex Hildyard" <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Tuesday, September 07, 2004 2:10 PM
Subject: Re: [nant-dev] Looping constructs in NAnt

> <target name="repeat">
>    <property name="var1" value="0" overwrite="false" />
>    <echo message="${var1}" />
>    <property name="var1" value="${convert::to-int(var1) + 1)" />
>    <call target="repeat" if="${convert::to-int(var1) < 10}" />
> </target>
>
> I'm not sure why you suggest that call doesn't have the right
> semantics... you're simply re-rolling your iterative approach back into
> a tail-recursive approach.  The above should do exactly the same as your
> repeat function, doesn't require pre-initialisation (the first time) and
> is almost as concise.

To be honest, the "overwrite=false" attribute hadn't occurred to me. I
would say you were onto a winner, but this does only work the first time
the loop gets called (as you point out yourself):

> also, any
> loop variables will need to be reset (externally) before the second and
> subsequent calls.
>

.. which tends to bring us back to where we started, doesn't it? Whether
you
use the "overwrite" attribute or not, you still need to set the loop
variable in an external
target prior to invoking the loop, when that loop is invoked multiple times
during a build.
It's not a big deal, but I'd still be happier if I could localise my loop
completely within a
single target.

>
> The other alternative is to wrap any loops in the <script> task.  You
> could use Project.Execute to perform any required tasks... the example
> above again:
>
> <target name="repeat-body">
>    <echo message="${var1}" />
> </target>
> <target name="repeat">
>    <script language="C#">
>      <code><![CDATA[
>        public static void ScriptMain(Project project) {
>          for (int i = 0; i < 10; i++) {
>            Project.Properties["var1"] = i;
>            Project.Execute("repeat-body");
>          }
>        }
>      ]]></code>
>    </script>
> </target>
>

This answers my example perfectly. But nevertheless it remains a very
particular
piece of script to perform a very particular looping task. I do see where
you're coming from
with your desire to keep NAnt declarative; but I would appreciate a more
generic construct
for arbitrary loops. To take the example above, you've used Project.Execute
to carry out
iterative processing, but what if the task at hand wasn't a simple loop, but
involved the evaluation
of a long sequence of terms? I wouldn't want to have to code all those
evaluations in C# just to gain the
benefit of invoking my chosen target in this way. I suppose my point is that
potentially each
loop would need a new block of accompanying script, and I don't find this an
attractive proposition. So ...

> If you use this often in your build, though, you would probably benefit
> from creating the repeat task

I think I'll make a patch as you suggest - for NAntContrib rather than for
NAnt - to accomplish a simple
<repeat> task that takes a single "condition" attribute. If anyone wants to
use it, it's there for them.

Regards,

Alex




-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=5047&alloc_id=10808&op=click
_______________________________________________
nant-developers mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/nant-developers

Reply via email to