James Duncan Davidson wrote:

> > On the point you raised in your email, I think properties should have
> > project-scope only and not target scope. Target scope implies a
> > functionality which is not there.
>
> +1 on project scope only. It's clearest from an API look onto a project
> (from within Java or any scripting environment)
>
> .duncan

Respectfully, I have to disagree.  Before I cause another landslide of messages
:-) let me say that with the *current* design, yes, perhaps properties should be
project-scope only.  That would certainly clarify some of the current confusion 
-
it would better express that some of the things some of us are trying to
accomplish with them are just not currently possible.

However, I find it extremely useful to have properties, macros, variables,
whatever you want to call them, occasionally defined only for a particular block
of commands, and often redefined for a different block of commands elsewhere -
i.e. target-scope.  Perhaps this means a redesign - run-time substitution of
properties, or a new "variable" type distinct from immutable properties.  (Not a
completely bad idea.)

In other words, no, I don't agree that Ant should be completely declarative.
Think about it for a bit.  When you really get down into the guts of it, any
build, be it Ant, Make, Perl, or whatever, is really procedural in nature.
Dependencies exist to ensure that certain steps can only happen in a certain
order.  Other steps can happen in any order.  But when you assemble it all, you
get an ordered, procedural build.  The declarative nature of the build scripting
language simply allows us to specify the steps in such a way that the tool can
determine which steps are needed, and in which order they need to be invoked.
IOW, the tool creates the procedure just before using it.  And to the build
author, the language within a target is fully procedural - immutable and 
ordered.
Only relationships between targets and their dependants are really declarative.

With that in mind, it is frequently useful to have procedural constructs to use
within a target.  I have run into situations where I needed all of the major 
ones
- iteration, conditionals, and variables.  When doing make builds on UNIX, this 
is
usually solved by using shell constructs in the command lists.  I *know* you 
have
all written a for or foreach loop in a make target before.  :-)  When using 
nmake
on Windoze, well, you're just up a creek with that one.  Ant, however, doesn't
*yet* (I know it's still in its infancy - no slight intended) have that kind of
expressive power.

More to the point - target variables.  Targets have dependencies.  Very often 
one
of the dependencies they have is ensuring that certain variables are set in
certain ways - perhaps containing directory names, file lists, tool versions,
whatever.  However, if variables are fully declarative and cannot be expressed
procedurally - as is the case with make - you cannot instruct the tool to set 
the
variables only when they are needed!  Instead you have to set them at the top of
the build instructions, every time, and hope for the best.  In the make world,
this often meant *days* of pondering over how to "fake out" the tool, and often
ended up requiring a refactoring of the build into multiple files - an ugly, 
ugly
solution.

The current suggested usage pattern of creating an "init" target containing all 
of
the property defs in it and setting this as a dependency in other targets 
suggests
that Ant does activate property defs procedurally - as does the fact that they 
are
defined as taskdefs.  I don't intend that as a criticism - it merely appears 
that
way to those of us who haven't been involved in the construction of the tool.
Those of us who read the list have now been corrected, of course.  :-)

So, I would suggest these things:
- If the property task is to remain a taskdef, evaluate it at runtime, with
mutability and all that entails.  Otherwise, change the DTD to clarify - perhaps
elevate property defs to parallel target defs (which leaves room for NO
misunderstanding).
- Provide some sort of target-scope variables, either mutable properties or a 
new
construct.  (BTW, true scoped variables would definitely be preferable to 
mutable
global properties in this particular context.)
- Consider providing other procedural constructs at the taskdef level.  Perhaps
something like a foreach task that can contain other tasks as its children.

Whew!  Did I cover it all?

roger


Reply via email to