ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jose Alberto Fernandez" <jalbe...@cellectivity.com>
Subject RE: ant 1.5.4 : Import
Date Thu, 31 Jul 2003 11:24:06 GMT
> From: Nicola Ken Barozzi [mailto:nicolaken@apache.org]
> 
> Jose Alberto Fernandez wrote, On 30/07/2003 21.14:
> 
> 
> > In escense, the idea is to associate a precedence to each 
> target (template in XSLT)
> > and when we say target X in a dependency, what is meant is 
> the highest precedence X.
> > No renaming necessary. Additionally, XSLT has an 
> <apply-imports/> which would be 
> > equivalent to having a task like: <call-import/> 
> > which evaluates a target with the same name as the current 
> target but comming from the
> > imported files (not taking into account the current target, 
> nor targets on files
> > importing this build file).
> > 
> > How to associate precedences, very easy. If we have something like:
> > 
> > 	a+---b---c   (1)
> >        \---d-+--e  (2)
> >         \--g  \-f  (3)
> > 
> > target precedence on each file will be:
> >   c=1 b=2 e=3 f=4 d=5 g=6 a=7
> > 
> > So if X is defined in c, e, and f; everybody will finish 
> using the one in f.
> 
> 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.

> This is the only issue that we now have with import I know 
> of, and the 
> above doesn't seem to solve it. Instead, it shows IIUC that 
> xslt has the 
> same -lets's call it- "issue"?
> 
> > 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.

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. 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.


> 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.

>    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.

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.

Jose Alberto

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message