ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nicola Ken Barozzi <>
Subject Re: ant 1.5.4 : Import
Date Thu, 31 Jul 2003 11:50:10 GMT

Jose Alberto Fernandez wrote, On 31/07/2003 13.24:

>>From: Nicola Ken Barozzi []
>>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 definition
>>>lower 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 
>>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 
>>  and those imported targets is available as 
>>-->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?
>>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 
>>  and those imported targets is available as 
>>  If there are multiple copies from the same target, the last 
>>  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?


   <target name="compile" depends="a.compile, b.compile"/>

With super.compile?

Nicola Ken Barozzi         
             - verba volant, scripta manent -
    (discussions get forgotten, just code remains)

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message