You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by Steve Amerige <St...@sas.com> on 2011/07/08 17:20:47 UTC

Equivalent:
Are the two statements below equivalent?

<antcall target="doit" InheritRefs="true" />
<runtarget target="doit" />

Enjoy,
Steve Amerige
SAS Institute, Deployment Software Developer

Re: Equivalent: Posted by Matt Benson <gu...@gmail.com>.
On Fri, Jul 8, 2011 at 10:49 AM, Dominique Devienne <dd...@gmail.com> wrote:
> On Fri, Jul 8, 2011 at 10:27 AM, Perrier, Nathan <np...@ptc.com> wrote:
>> No, because antcall creates a new project underneath the hood, whereas runtarget (antcontrib task) does not.
>
> I would add that <runtarget> (and <antcall> as well in fact) goes
> against the Ant philosophy of having declarative builds using targets
> with proper dependencies between them, where by "dependencies" I mean
> that target just state their "requirements" and should not care when
> or in which order those requirements are fulfilled,  since that's the
> job of the "dependency manager" to analyze the graph of targets and
> order them such that each one runs only once and in the proper order,
> detecting circular references. Targets are not functions that one
> would call at will, leading to procedural as opposed to declarative
> builds. <macrodef> usage should eliminate the need for most
> <runtarget> usage and is preferred in general.
>
> In more practical terms, <antcall> does indeed create a new project
> (i.e. a new "scope"), which means that any property it sets will not
> be visible to the build that used <antcall>. <runtarget> does not
> create a new Project, so all properties set *are* visible to the
> "caller", and it achieves that via a loophole in Ant's API which is
> not plugged for backward-compatibility reasons.
>
> Using <antcall> and <runtarget> is IMHO a symptom of using Ant and
> builds with a wrong (procedural) mindset. I've created lots of large
> and complex builds in the past without any, so it's certainly not
> necessary to idiomatic Ant usage, although it remains quite popular to
> many :) My $0.02. --DD

And since Ant 1.6 I have never found a problem that would formerly
have been solved by e.g. <antcall> that couldn't be solved with
<macrodef>, and so reducing dependencies on external libraries while
still avoiding the overhead of the additional project instance.

Matt

>
>> -----Original Message-----
>> From: Steve Amerige [mailto:Steve.Amerige@sas.com]
>>
>> Are the two statements below equivalent?
>> <antcall target="doit" InheritRefs="true" />
>> <runtarget target="doit" />
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
> For additional commands, e-mail: user-help@ant.apache.org
>
>

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


runtarget vs. macrodef for Procedural Ant Programming

Posted by Steve Amerige <St...@sas.com>.
Hi all,

What are the pros/cons of choosing runtarget vs. macrodef as "functions" under these assumptions:

    1. Ant is going to be used as a procedural language for complex coding.  Please just accept this assumption. :-)
    2. No more than a page or so of coding should be in any one macrodef or runtarget to keep the business logic understandable.
    3. Ant-Contrib is going to be used within the functions.
    4. The code should be reasonably modular to encourage creating reusable code with style choices that help to differentiate 
between public APIs, private APIs, volatile variables (any previous value is discarded), and test APIs.
    5. Ant 1.7 is going to be used.

I tend to prefer runtarget over macrodef for zero-argument functions for these reasons:

1. The syntax of a target name allows for more characters than a macrodef name.
2. Eclipse Outline view allows for me to create the distinction between public and test APIs vs. private APIs.
3. I'm concerned that some constructs if put in a macrodef will fail that would otherwise succeed in a target.

TARGET NAME SYNTAX vs. MACRODEF SYNTAX

A macrodef name cannot begin with "." or "-" and cannot have embedded spaces, but a target can.  With runtarget, I can use naming 
conventions that deal with the problem that Ant 1.7 has very limited scoping capabilities.  I use these conventions for names:

    * public names       publicAPIName
    * private names      _privateAPIName or -privateAPIName (the latter discourages command-line use)
    * volatile names     __volatileName
    * test names         _.testAPIName

ECLIPSE OUTLINE VIEW

One advantage of using runtarget is that in Eclipse targets can be associated with different icons:

    * better - Target-icon in Outline View: the description attribute changes the icon to filled vs. unfilled if absent
    * weaker - Macrodef-icon in Outline View: the description attribute does not change the icon

I can therefore use the description attribute for all public and test APIs and leave it off for all private APIs.

CONCERNS ABOUT MACRODEF LIMITATIONS

I'm concerned that there are things that will fail if called by macrodef that wouldn't fail if called by runtarget.  I seem to 
recall something about nested something or other or dealing with parameter substitution... I can't recall, it was something I 
googled somewhere.  This is just a worry... if I'm wrong, please let me know.

GENERAL

Are there any things that I won't be able to do with macrodef that I could do with runtarget (and the other way around)?  Also, are 
there any performance considerations to prefer one over the other?  How significant are they?

Because of the syntax and Eclipse issues above, I tend to prefer runtarget over macrodef for zero-argument functions.  Is there any 
compelling reason to argue against using runtarget given the assumptions above?

Enjoy,
Steve Amerige
SAS Institute, Deployment Software Developer


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


macrodef, runtarget, antcall

Posted by Steve Amerige <St...@sas.com>.
Hi Dominique and all,

You've spotted exactly the issue at hand. :-)  Please accept for purposes of discussion the requirement that Ant MUST be used in a 
procedural manner.  Plans to use scriptdef and Groovy are in the works, but that's not now.  So, the question is what are the best 
set of practices to do in the case that only Ant and Ant-Contrib are allowable and one wants to have reasonably modular-looking code 
that differentiates between public APIs, test APIs, internal "functions and macros"?

I was thinking that <runtarget> would serve as a function call mechanism, but what I've heard in this mailing list is that I should 
use <macrodef> instead.  Are there any things that I won't be able to do with macrodef that I could do with runtarget (and the other 
way around)?  The one advantage of using runtarget is that in Eclipse it shows up in Outline view as an unfilled target.  This makes 
it easy to categorize code as follows:

* Filled-target-icon in Outline View: "Public" API Tasks
* Unfilled-target-icon in Outline View: "Local Tasks" that are either major portions of a task or are "Test" APIs
* Macrodef-icon in Outline View: "Reusable code" that I don't think of as a task or subtask
* Scriptdef-icon in Outline View: is not helpful because the scriptdef name isn't shown (compared to target and macrodef elements)

And, with conventions being followed to help distinguish between public APIs (publicAPIName), test APIs (_.testAPIName), internal 
"functions" and macrodefs (_internalFunctionMacrodefEtc), the code is reasonably easy to read.

Believe it or not, the ability or organize code better feels like a good reason to prefer runtarget over macrodef.  I'm still 
curious as to whether there are any practical (e.g., perfomance) reasons for favoring macrodef over runtarget.

Gotta love this group... good technical discussions here!

Enjoy,
Steve Amerige
SAS Institute, Deployment Software Developer

* P.S.

On 7/8/2011 11:49 AM, Dominique Devienne wrote:
> Using<antcall>  and<runtarget>  is IMHO a symptom of using Ant and
> builds with a wrong (procedural) mindset. I've created lots of large
> and complex builds in the past without any, so it's certainly not
> necessary to idiomatic Ant usage, although it remains quite popular to
> many:)  My $0.02. --DD



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


Re: Equivalent: Posted by Matt Benson <gu...@gmail.com>.
On Fri, Jul 8, 2011 at 10:55 AM, Perrier, Nathan <np...@ptc.com> wrote:
> Agreed, I try to use antcall as little as possible.  It also tends to
> eat up memory if you have a ton of antcall tasks in a large build
> framework.
>
> Macrodefs are a nice substitute, but they really need an "if/else"
> attribute.  I find that I often have targets that are just wrappers for
> macrodef or use antcontrib's if/else tasks to accomplish this.

Embedding some unit of work in a target that is conditionally executed
*is* the "Ant way" of doing things.  :)

Matt

>
> -----Original Message-----
> From: Dominique Devienne [mailto:ddevienne@gmail.com]
> Sent: Friday, July 08, 2011 10:50 AM
> To: Ant Users List
> Subject: Re: Equivalent: <ant
>
> On Fri, Jul 8, 2011 at 10:27 AM, Perrier, Nathan <np...@ptc.com>
> wrote:
>> No, because antcall creates a new project underneath the hood, whereas
> runtarget (antcontrib task) does not.
>
> I would add that <runtarget> (and <antcall> as well in fact) goes
> against the Ant philosophy of having declarative builds using targets
> with proper dependencies between them, where by "dependencies" I mean
> that target just state their "requirements" and should not care when
> or in which order those requirements are fulfilled,  since that's the
> job of the "dependency manager" to analyze the graph of targets and
> order them such that each one runs only once and in the proper order,
> detecting circular references. Targets are not functions that one
> would call at will, leading to procedural as opposed to declarative
> builds. <macrodef> usage should eliminate the need for most
> <runtarget> usage and is preferred in general.
>
> In more practical terms, <antcall> does indeed create a new project
> (i.e. a new "scope"), which means that any property it sets will not
> be visible to the build that used <antcall>. <runtarget> does not
> create a new Project, so all properties set *are* visible to the
> "caller", and it achieves that via a loophole in Ant's API which is
> not plugged for backward-compatibility reasons.
>
> Using <antcall> and <runtarget> is IMHO a symptom of using Ant and
> builds with a wrong (procedural) mindset. I've created lots of large
> and complex builds in the past without any, so it's certainly not
> necessary to idiomatic Ant usage, although it remains quite popular to
> many :) My $0.02. --DD
>
>> -----Original Message-----
>> From: Steve Amerige [mailto:Steve.Amerige@sas.com]
>>
>> Are the two statements below equivalent?
>> <antcall target="doit" InheritRefs="true" />
>> <runtarget target="doit" />
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
> For additional commands, e-mail: user-help@ant.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
> For additional commands, e-mail: user-help@ant.apache.org
>
>

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


Re: Equivalent: Posted by Dominique Devienne <dd...@gmail.com>.
On Fri, Jul 8, 2011 at 10:55 AM, Perrier, Nathan <np...@ptc.com> wrote:
> Agreed, I try to use antcall as little as possible.  It also tends to
> eat up memory if you have a ton of antcall tasks in a large build
> framework.

Yep. Large builds tend to be hierarchical and I used lots of <subant>,
which forks new Ant instances, avoiding the EOMs one can run into with
<antcall>.

> Macrodefs are a nice substitute, but they really need an "if/else"
> attribute.  I find that I often have targets that are just wrappers for
> macrodef or use antcontrib's if/else tasks to accomplish this.

Indeed built-in Ant lacks such conditionals. I also used <ac:if> and
co. initially, and later a custom <bm:sequential> such supported
attributes like if/ifTrue/ifSet/unless/os/when for conditional
support. It's been a long discussion to support those in Ant which so
far always resulted in keeping the status-co in this regard. --DD

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


RE: Equivalent: Posted by "Perrier, Nathan" <np...@ptc.com>.
Agreed, I try to use antcall as little as possible.  It also tends to
eat up memory if you have a ton of antcall tasks in a large build
framework.

Macrodefs are a nice substitute, but they really need an "if/else"
attribute.  I find that I often have targets that are just wrappers for
macrodef or use antcontrib's if/else tasks to accomplish this.

-----Original Message-----
From: Dominique Devienne [mailto:ddevienne@gmail.com] 
Sent: Friday, July 08, 2011 10:50 AM
To: Ant Users List
Subject: Re: Equivalent: <ant

On Fri, Jul 8, 2011 at 10:27 AM, Perrier, Nathan <np...@ptc.com>
wrote:
> No, because antcall creates a new project underneath the hood, whereas
runtarget (antcontrib task) does not.

I would add that <runtarget> (and <antcall> as well in fact) goes
against the Ant philosophy of having declarative builds using targets
with proper dependencies between them, where by "dependencies" I mean
that target just state their "requirements" and should not care when
or in which order those requirements are fulfilled,  since that's the
job of the "dependency manager" to analyze the graph of targets and
order them such that each one runs only once and in the proper order,
detecting circular references. Targets are not functions that one
would call at will, leading to procedural as opposed to declarative
builds. <macrodef> usage should eliminate the need for most
<runtarget> usage and is preferred in general.

In more practical terms, <antcall> does indeed create a new project
(i.e. a new "scope"), which means that any property it sets will not
be visible to the build that used <antcall>. <runtarget> does not
create a new Project, so all properties set *are* visible to the
"caller", and it achieves that via a loophole in Ant's API which is
not plugged for backward-compatibility reasons.

Using <antcall> and <runtarget> is IMHO a symptom of using Ant and
builds with a wrong (procedural) mindset. I've created lots of large
and complex builds in the past without any, so it's certainly not
necessary to idiomatic Ant usage, although it remains quite popular to
many :) My $0.02. --DD

> -----Original Message-----
> From: Steve Amerige [mailto:Steve.Amerige@sas.com]
>
> Are the two statements below equivalent?
> <antcall target="doit" InheritRefs="true" />
> <runtarget target="doit" />

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


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


Re: Equivalent: Posted by Dominique Devienne <dd...@gmail.com>.
On Fri, Jul 8, 2011 at 10:27 AM, Perrier, Nathan <np...@ptc.com> wrote:
> No, because antcall creates a new project underneath the hood, whereas runtarget (antcontrib task) does not.

I would add that <runtarget> (and <antcall> as well in fact) goes
against the Ant philosophy of having declarative builds using targets
with proper dependencies between them, where by "dependencies" I mean
that target just state their "requirements" and should not care when
or in which order those requirements are fulfilled,  since that's the
job of the "dependency manager" to analyze the graph of targets and
order them such that each one runs only once and in the proper order,
detecting circular references. Targets are not functions that one
would call at will, leading to procedural as opposed to declarative
builds. <macrodef> usage should eliminate the need for most
<runtarget> usage and is preferred in general.

In more practical terms, <antcall> does indeed create a new project
(i.e. a new "scope"), which means that any property it sets will not
be visible to the build that used <antcall>. <runtarget> does not
create a new Project, so all properties set *are* visible to the
"caller", and it achieves that via a loophole in Ant's API which is
not plugged for backward-compatibility reasons.

Using <antcall> and <runtarget> is IMHO a symptom of using Ant and
builds with a wrong (procedural) mindset. I've created lots of large
and complex builds in the past without any, so it's certainly not
necessary to idiomatic Ant usage, although it remains quite popular to
many :) My $0.02. --DD

> -----Original Message-----
> From: Steve Amerige [mailto:Steve.Amerige@sas.com]
>
> Are the two statements below equivalent?
> <antcall target="doit" InheritRefs="true" />
> <runtarget target="doit" />

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


Re: Equivalent: antcall with inheritrefs vs. runtarget

Posted by Steve Amerige <St...@sas.com>.
Thanks, Nathan.  So, aside from performance and implementation issues, are they equivalent?  That is, is there anything observable 
in a script as a practical matter between these two idioms?  If not, I'd think I'd usually want runtarget instead of antcall with 
inheritrefs=true.

On 7/8/2011 11:27 AM, Perrier, Nathan wrote:
> No, because antcall creates a new project underneath the hood, whereas runtarget (antcontrib task) does not.
>
> -----Original Message-----
> From: Steve Amerige [mailto:Steve.Amerige@sas.com]
> Sent: Friday, July 08, 2011 10:21 AM
> To: Ant Users List
> Subject: Equivalent:<ant
>
> Are the two statements below equivalent?
>
> <antcall target="doit" InheritRefs="true" />
> <runtarget target="doit" />
>
> Enjoy,
> Steve Amerige
> SAS Institute, Deployment Software Developer



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


RE: Equivalent: Posted by "Perrier, Nathan" <np...@ptc.com>.
No, because antcall creates a new project underneath the hood, whereas runtarget (antcontrib task) does not.

-----Original Message-----
From: Steve Amerige [mailto:Steve.Amerige@sas.com] 
Sent: Friday, July 08, 2011 10:21 AM
To: Ant Users List
Subject: Equivalent: <ant

Are the two statements below equivalent?

<antcall target="doit" InheritRefs="true" />
<runtarget target="doit" />

Enjoy,
Steve Amerige
SAS Institute, Deployment Software Developer