Sorry if the mail becomes long, I have difficulty in deciding what to snip ;-)


Costin Manolache wrote, On 07/08/2003 15.56:

Nicola Ken Barozzi wrote:

Thanks for the overview, Nicola !

Just to get you up to speed, the current issue is about multiple
inheritance, and how the current system allows cross-import (unwanted?)
side-effects, as Conor has brilliantly shown.

What I'm not sure I understand is what import has to do with multiple inheritance :-)

Because we can import two targets with the same name from different files. Making them work together is conceptually similar.

You could try to import 2 classes with the same name in java. It's a syntax error - and if it happen, you must use qualified names.

Yes, most build files have a target named "build" - but I don't know why
would you think about inheritance and OO instead of just qualified names.

I don't know _any_ programming language where import is used for
inheritance.

Well, I pointed out xslt, what about that? ;-)

As has been pointed out in these threads, Ant is a different beast, and should be treated differenty.

What's the syntax for the
prefixed targets/properties ?

prefix+targetname

example:
 prefix="a"
 name="b"
 result="ab"


Hmm. Some delimiter would be good to have. a.b, a-b, a::b, etc.
It would make things easier to read and understand.

not : , as it mixes with namespaces not :: , too cluttery not - , used in many xml langiages in compound names . could be ok

It would also be nice to default to the project name
( and require it to be unique, or use the explicit prefix
only if 2 build files have the same name ).

OOTOMH could be a nice thing.

- add <include/> task, like entity includes
- add <override-target/> task to override targets

Is this "override-target" a substitute for <extends> and OO use of ant ( i.e. a buildfile == class, target==method ) ?

In a sense yes, but not quite. Import does not fully encapsulate the calling buildfile. @see XSLT include and import for a more similar concept.

If so, wouldn't be more intuitive to just use the real concept - i.e.
extends and inheritance ?

Dunno.

I know python has a very nice namespacing mechanism where you can replace
or add methods dynamically to an object, but I don't know if this is
desirable for ant.

KISS. Personally I don't need that (yet) I guess.

Well, KISS is my concern as well, for <import> ( which at least in my mind is _very_ different from "extend" ).

It is, I agree.

I preffer to use import to just import
entire files, instead of some attributes and sophisticated rules to
determine what target is visible and what target is overriden.

Then call it <include>, it's already proposed.

And if people need an OO feature for ant - that's fine, they can add special
tasks ( <exted>, <override>, etc ).

Hey, that's what we are talking about! IOW, what should Ant give me to get the features I want?


<include> ok, already decided
<override> ok, already decided
<import> ?

Threads about import (in order):
  1 - ImportTask ant 1.6
  2 - ant 1.5.4 : Import
  3 - override

From thread 2 I wrote:
"
multi-import(import a,b)
 target test depends=a.test, b.test

a
 target critical
 target test depends=critical

b
 target critical
 target test depends=critical


Here "critical" means a.critical to a and b.critical to b, but since they reference a generic "critical", they get the only one that remains after being redefined. The problem is that I did not redefine it in the main buildfile! "

Can this be resolved by making all targets qualified after the build file is read ?

This is what Conor seems to propose IIUC, and what others are not keen on, and instead talk more about the xslt-type import.

Well, Conor has one more vote then :-)

XSLT is not the easiest XML format ( I don't know many people to consider writting an XSTL is easier than writting an ant build file :-)
And the fundamental problem ( IMO ) is using the wrong concept.


We are talking about OO concepts and inheritance - in <import> context.

Well, we are not. We are referencing those concepts, but it's not the same thing.


If we have so much trouble understanding how <import> would be used for inheritance, what about all the users who may be java programmers ( where import has a very intuitive meaning, and so does extends ).

If it's just a naming issue, let's call it XYZ, I honestly don't care.

Just to be clear: current import is *not* <projectref>. It is not meant to encapsulate another buildfile, and the basedir resolving and the non-namespacing of properties is very clear about this.

Just remember that we are not talking about renaming properties, or
resolving basedirs, so it's not full encapsulation, but just
dependency-shielding.

Well, we seem to be talking about which target will be visible - with
private/public and all this. Very far from java import - where all you can talk about is qualified names
if you have 2 classes with the same name.

Because Java does not have multiple inheritance, and even more does not have automatic multiple inheritance. I agree that this is a different concept.


I have not yet made up my mind, but it seems that ATM there is a reason
favor some kind of "namespacing" because I see more harm than good in
side-effects that come out of not doing it. How this can still solve my
usecase is yet to be seen.

Maybe import shouldn't solve all use cases - just have a different task that solves overriding/replacing some targets.

Ok, so you haven't read all the thread ;-)

Maybe it's better if you take a bit of time to reread the thread, as we are repeating stuff here.

When you look at a build.xml, all targets that don't have prefix are
resolved to the current build file - it's pretty easy to understand.

That mean you won't be able to use import for crazy overrding of
some targets from one file with targets from other file - but if there is
a real need for that i have no problem with a python-like mechanism where
you can add/replace methods in an object at runtime. As long as it's
not disguised as <import> :-)

Well, IMHO I personally don't see a real, strong, compelling reason to have targets have crosstalk between themselves, but I do have an equally strong need to import dependencies.

With qualified names, you can have both.

Hmmm...

As I have outlined before, imagine I import a file that has a compile
and test targets.

 target compile
 target test depends=compile

I want to be able to do "ant compile" and have it compile. Thus the
compile target should not be renamed.

If this is the only "compile" target in all the imported files, then you should be able to say "ant compile".


If you import 2 files, each having a "compile" target, then you should
use qualified names. Like in java import.

Ok, this is clear, you are saying we should not have an automatic "winner" in case of multiple colliding import names.


Let's see the rest...

Then when I want to insert a pre-condition to the compile target, I want
to be able to redefine the compile target.
Reusing it in a differently-renamed target is not ok, as when I call
"test", it will not have a dependency to the new version of the target.

So
 target compile
 target newcompile (call:prestuff, compile, poststuff)
 target test depends=compile

That's a nice use-case - but why do you think this is a use case for
"import" ?

Because I called it this way, that's all ;-)

Just use a <rename-target> target, or some <pre>/<post> or <extend>.

In fact, as I have explained, Conor proposed <override-target>, and I like it. But this is only about a a single import, the real issue discussed here is the multiple one.


If I call newcompile, it works but calling test will not call the new
one, thus making it impossible for me to *decorate* the compile target,
thus specializing the template.

Makes sense to me - if import would allow this to happen few people will
be able to understand a build file.
>
So I consider a good thing that import doesn't allow you to "decorate", but instead you should use a specialized task for this use case.

You mean that a user must do:

 <override-target name="xxx">

 instead of

 <target name="xxx"> (implicit override)?

I'm fine with it, no problem here, again it has been proposed and accepted, but not the issue here.

The question is: after a multiple import, which compile target becomes
the "default" one, ie the one without renaming?

None, if 2 targets with the same name are found, you must
use qualified names for both ( when calling from outside - all dependencies
and calls from inside an imported build.xml file would use the short name ).

I get your point, same as you described above. Not sure, but OOTOMH I think it's ok.

Second question: how do we deal with the fact that targets that are not
even used have crosstalk between themselves?

I don't think you can have crosstalk if you follow the rule that everything is qualified if it has the same name.

Two points here:

 - Crosstalk can happen in form of properties
 - Of course you won't have crosstalk if you use qualified names, this
   is what Conor says

And most of all: how to solve the last two points while keeping it
possible for me to retain the use-cases?

By adding specialized tasks for your use case ?

Let's see:

<include>

No problem here, any collision is an error

<override-target>

I am overriding the previous defined target, and can refer only to the immediately previous one as original.targetname. Overriding can be done multiple times, nesting the calls.

<import>

Like include, but gives me the possibility of referring to the imported tasks with a fully qualified name in any case. If there is only one version of a target, it's also available with the original name.

<Still conused about this [] part> [The "namespace" name has to be specified as a prefix by the one that imports the file, else the project name is used. Projects that are imported must have a name.]

If a project imports clashing target names, and thus namespacing is needed, I can still use <override-target> or <target> to define a target with the original name.

IMPORTANT PART

Use case:

multi-import(import a,b)
  target test depends=a.test, b.test

a
  target compile
  target test depends=compile
b
  target compile
  target test depends=compile

With namespacing I would get:

a
  target a.compile
  target a.test depends=a.compile
b
  target b.compile
  target b.test depends=b.compile

Now If I redefine compile

multi-import(import a,b)
  target test depends=a.test, b.test
  target compile depends=a.compile,b.compile

Seems ok to me  :-)

Now for Nick's usecase:

"
Nick Chalko wrote, On 01/08/2003 9.37:

I used this "feature" in centipede.

The release antlib has a target called tag-and-release, but it
depends on a target called tag However tagis expected to be defined
in a different antlib. Currently it is defined in cvsbuild, but it is
open for someone to make a vssbuild antlib.

So I do think cross talk is a "feature" but a feature that can be
hard to grok.
"

  multi-import(import release,cvsbuild)

  release @importable="only"
    target tag-and-release depends=tag

  cvsbuild
    target tag


Seems that it should work with the above system.

Also

  multi-import(import release,cvsbuild,vssbuild)

Would make it necessary for me to do:

  override-target tag depends=cvsbuild.tag

As you see, for this usecase, <include> is not strong enough, as I
cannot override, and complete namespacing prevents me from overriding
the dependency chain.

It's like saying <copy> is not strong enough to compile java code :-)

It isn't? ;-P

Anyway, it seems that all this discussion has brought us back to what I had proposed after Conor pointing out the issue:

"
Nicola Ken Barozzi wrote, On 30/07/2003 10.45:
...
> OTOMH this could be solved by rewriting all dependencies that are not
> in the import line.
>
>               (1)---a
>  multi-import (2)---b
>               (3)---c---d
>
So rewriting should block collisions between (1), (2), (3), but
enable them inside those lines.

What had been proposed is using "fully qualified" names in targets
that I do not want to be redefined, which could be ok conceptually,
but the issue is that the implications of sideways crosstalk between
import lines are not transparent to the user, and thus should be
avoided.

What I need is to be able to import build dependencies along with the
 targets. Probably the above solution should fix this error and make
it work, no?
"

Thanks for taking time to discuss this guys, I appreciate :-)

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



Reply via email to