> From: Stefan Bodewig [mailto:[EMAIL PROTECTED] 
> On Tue, 11 Nov 2003, Jose Alberto Fernandez 
> 
> > To me macrodefs are for writing all those tasks that I am 
> too lazy, or 
> > they are too simple for me to need to go and write and 
> maintain some 
> > Java code.
> 
> I'm not sure that this is the intention of <macrodef> - maybe 
> you would rather use <scriptdef> with beanshell as your 
> scripting language then?
> 

I do use it extensively. And believe me, every time we have a 
syntax or logical error in the code it takes 1o times longer
to find it. Line numbers never match with that of the srcfiles.
But back to the topic.

I want macrodef for when all I need to do is to put toguether
a group of calls to other tasks in a sequence, which could be
quite complex, but it does not require any additional computation
from my part:

<macrodef name="preferential-copy">
  <attribute name="app-pref.name"/>
  <attribute name="app-pref.dir/>
  <sequential>
    <mkdir dir="${app-prefs.dir}"/>
    <dependset>
        <srcfileset dir="${basedir}">
            <include name="${app-prefs.name}/**"/>
            <include name="${containers.dir}/${app-prefs.name}/**"/>
            <include name="${descriptor.dir.app}/${app-prefs.name}/**"/>
            <include 
name="${descriptor.container.dir.app}/${app-prefs.name}/**"/>
        </srcfileset>
        <targetfileset dir="${app-prefs.dir}"/>
    </dependset>
    <if>
      <available file='${descriptor.container.dir.app}/${app-prefs.name}' 
type="dir"/>
      <then>
        <copy todir='${app-prefs.dir}'>
            <fileset dir="${descriptor.container.dir.app}/${app-prefs.name}" 
includes="**"/>
        </copy>
      </then>
    </if>
    <if>
      <available file='${descriptor.dir.app}/${app-prefs.name}' type="dir"/>
      <then>
        <copy todir='${app-prefs.dir}'>
            <fileset dir="${descriptor.dir.app}/${app-prefs.name}" 
includes="**"/>
        </copy>
      </then>
    </if>
    <if>
      <available file='${containers.dir}/${app-prefs.name}' type="dir"/>
      <then>
        <copy todir='${app-prefs.dir}'>
            <fileset dir="${containers.dir}/${app-prefs.name}" includes="**"/>
        </copy>
      </then>
    </if>
    <if>
      <available file='${app-prefs.name}' type="dir"/>
      <then>
        <copy todir='${app-prefs.dir}'>
            <fileset dir="${app-prefs.name}" includes="**"/>
        </copy>
      </then>
    </if>
  </sequential>
</macrodef>

Today, I need to do this by calling <antcall> because I need to pass diferent
parameters in different places. It will look much better that instead of:

        <antcall target="prefs.app">
            <param name="app-prefs.name" value="war-res"/>
            <param name="app-prefs.dir" value="${war-res.app}"/>
        </antcall>

I can just say:

        <preferential-copy app-prefs.name="war-res" 
app-prefs.dir="${war-res.app}"/>

You can see that using scriptdef to do this job is absolute madness. Since all 
you need is
to put toguether some tasks.

> > Substitution is the least interfearing behavior.
> 
> I hear you and to a certain degree I agree with you.  
> Actually I haven't really made up my mind myself yet - no 
> vote from me so far.
> 
> > But if <atributes> modify properties, then there is no way 
> for me to 
> > stop them for happening.
> 
> In which situation would "<atributes> modify properties" have 
> negative effects on what you are planing to do with 
> <macrodef>?  Do you have an enlightening example?
> 

  <macrodef name="myMacro">
    <attribute name="debug"/>
    <element name="code"/>
    <sequential>
      <if>
        <istrue value="${debug}">
        <then>
          <echo>myMacro: Entering my macro</echo>
          <code/>
          <echo>myMacro: Entering my macro</echo>
        </then>
        <else>
          <code/>
        </else>
      </if>
    </sequential>
  </macrodef>

So here we have this simple macro that adds some debug information.

So I use it like:

   <myMacro debug="true">
     <code>
       <my.javac srcdir="test/src" .../>
     </code>
   </myMacro>

Still, very naïve code. Until you see that the definition of my.java is:

<presetdef name="my.javac">
   <javac srcdir="src" destdir="classes" deprecation="${deprecation}"
          debug="${debug}"/>
</presetdef>

No here the intention of the code writer was to control javac using the
debug property. But just because I decided to write myMacro with an
attribute called debug, I am changing the behavior of my.java. (if we use 
locals)

If this one is not convinsing enough, I am sure we can build one based on
this model.

If we were doing replacement, this will not happen. The attribute "debug"
will only affect the <if> and not the things inside <code/>.

But wait, what if I actually wanted to change the property?
Well, in that case you can introduce the <local> yourself
as part of the code of the macro:


  <macrodef name="myMacro">
    <attribute name="debug"/>
    <element name="code"/>
    <sequential>
      <local property="debug" value="$(debug)">
        <if>
          <istrue value="${debug}">
          <then>
            <echo>myMacro: Entering my macro</echo>
            <code/>
            <echo>myMacro: Entering my macro</echo>
          </then>
          <else>
            <code/>
          </else>
        </if>
      </local>
    </sequential>
  </macrodef>

Here, I guess I need diferent syntax so I can talk about the attribute
and the property at the same time.

So as I said, textual replacement is not only the one least surprising
but it is also the most flexible. You cannot do it the other way around.

Jose Alberto

> Stefan
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to