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
