Jose Alberto Fernandez wrote, On 31/07/2003 13.24:
...From: Nicola Ken Barozzi [mailto:[EMAIL PROTECTED]
Wait a second, does this mean that there is crosstalk between the lines 1, 2, 3?
Yes, there is crosstalk and at least in XSLT this is a good thing. It means that you can write a bunch of files with groups of templates on each, and then by just importing them into one buildfile all the pieces can interact with each other. In that way if I want to replace one group of templates in a diferent project I can just change the import line for that particular group and the behaviour changes.
We use this technique extensively in our system at work and it makes life extremely easy and modular. So in may opinion this is a good thing.
That's what I do too, just that I don't never had the need or ever thought of doing it with targets that are not redefined in the base one.
If you say that you use it and benefit from it, I believe you, and makes me feel better :-)
So what I thought was a bug is instead a feature; the important thing is that this "feature" is correctly documented.
If X calls <call-import/> then it will call the X in e,since it is the highest definitionlower than the X in f.
Notice that there is no need for renaming anything, just adding a precedence attribute
to each target. And precedences are assigned in a depth-first-search manner.
But this is a step back it seems. With naming it's much easier to call the selected target without checking import orders.
I can say: call the f.X target, because I know that I want what f's X does, without having to check the hierarchy.
Tell me about on succesful OO language in which you are alowed to call the super of 10 levels above without visisting the inmediate super definition. This idea of jumping around as one pleases is just as bad as programming with unstructured GOTOs. GOTOs allow you to do whatever you want, and that is why they have been doommed. I really do not think it is a good idea.
I am not aware of all the implications, so I tend to believe you.
In fact, my original version had an apply-import tag. But then it became impossible to use them in the @depends attribute, so I did the renaming of the target name to super.targetname.
Then, I don't remember the details, super.targetname was not liked so we switched to the buildname.targetname. Should look in the archives.
As per the example you mention, I think it can be rewritten using the XSLT model. But I am not sure about the details.
XSLT forces <imports> to be at the top of the file, which simplifies precedence computation.
We could enforce the same (what it really means, is no imports inside targets).
Well, AFAIK if we put imports at the top, what you show is what happens, as each import is executes recursively.
Yes, as long as you assigned the precedence for the imported targets before you assign preferences for any target in the importing file, it will just work. As I said, the only thing forbidden is having the <import/> inside a target (and not at top level).
Well, hope you consider this, as an alternative. I think it is much more easy to handle
and if XSLTs do not need more that this, I do not see why ANT will need much more.
From this mail it still seems to me that renaming is easier to use and les ambiguous.
What remains is the possible issue of intra-buildfile crosstalk.
This makes it even more important to have an importable=true attribute in the project file, as this has to be taken into account.
It still seems that shielding buildfiles between import lines is the most intuitive way of working for the users... let's see.
It can be summarized as:
"
Each import will insert the imported file in the importing file.
If there are name clashes, the importing file targets take precedence,
and those imported targets is available as importedfilename.targetname.
"
-->Which makes me think BTW that properties should be renamed in the same fashion.<--
Aha!, now you need to rename properties.
Not that I need, it was just a musing, that stems from the assumption that buildname.targetname is to use...
How about properties comming from propertyfiles? How do you know which ones should not be renamed because they are from files and which ones should because they come from the import? I can show you many examples in which you cannot determine one way or the other.
... which, give the above, could simply mean that buildname.targetname is not to prefer... hmmm...
The above description is seems clear, concise and intuitive.
The problem is: what if I want to use one of the common imported targets that I did no redefine?
Let's say that I want to use the "init" target in the below example. Which one is called?
Ha.
So using the xslt-like method, it becomes:
"
Each import will insert the imported file in the importing file.
If there are name clashes, the importing file targets take precedence,
and those imported targets is available as importedfilename.targetname.
If there are multiple copies from the same target, the last definition
takes precedence. Note that the target that takes precedence will be
used in all dependencies, regardless to which buildfile they came from.
"
That is why you have <call-imports/> for. It allows you to go up on the hierarchy. As I said, you may need to write your things a little different, and we may need something additional, I do not know, but code rewriting is not the solution for multiple inheritance, it will just create spaggetti builds very quickly.
As I said before, call-imports cannot be used in dependencies, but I understand the concept.
Example:
File a.xml
<project name="first"> <target name="a" depends="init"> <echo value="inita"> </target> <target name="init"> <echo value="initb"> </target> </project>
File b.xml
<project name="second"> <target name="b" depends="init"> <echo value="b"> </target> <target name="init"> <echo value="inita"> </target> </project>
file build.xml
<project name="main" default="run"> <import file="a.xml" /> <import file="b.xml" /> <target name="run" depends="a,b"/> </project>
I just want to see a programming language inheritance model in which you can write inheritance like this and that works in your proposed way and still allows writing using build fragments.
Something like:
class A { void init() { print("initA"); } void a() { init(); print("A"); } void compile() { print("compile"); } }
class B { void init() { print("initB"); } void b() { init(); print("B"); } }
class build extends A, B { void run() { a(); b(); } }
Will this execute as expected in C++, C#? What if
I want to override init()? Can I use in B the compile() definition of A? I need that to be able to write import fragments which I think we want.
You are writing completely reentrant classes here, not imported bits. The above are namespaced, the <import> way is different.
So, to me thi point is not as much how many features we have, but having a consistent set of features that will work properly all the way and will allow us to write understandable builds.
I need the possibility of calling super targets and redefining them. The current version tries to address it, but some issues have come out.
How this is done I don't care, as long as it works, so I agree with you on this.
So, back to square one: what do we do about multiple inheritance?
My current opinion, that stems from your first paragraphs in this mail, is that the current model of overriding, similar to XSLT, can remain, and the manual has additional info as I tried to summarize above.
Now for the last part: projectname.targetname or super.targetname?
Here is a general case:
I have two imported buildfiles, that both contain a "compile" target. I want to import both and make them both run. How can I do it?
Currently:
<target name="compile" depends="a.compile, b.compile"/>
With super.compile?
-- Nicola Ken Barozzi [EMAIL PROTECTED] - verba volant, scripta manent - (discussions get forgotten, just code remains) ---------------------------------------------------------------------
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]