ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Roger Vaughn <rvau...@seaconinc.com>
Subject Re: Why Properties became immutable
Date Tue, 25 Jul 2000 00:58:55 GMT
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



Mime
View raw message