[Templates] manipulating lists inside MACRO not the same as outside

Paul Seamons mail@seamons.com
Tue, 5 Dec 2006 16:15:53 -0700


I believe that when you create a macro, that internally the macro is stored=
 as=20
a code sub in the stash.  Therefore when you do MACRO macro_list ... you ar=
e=20
storing a coderef in the stash under the name macro_list.  If you use the=20
macro in normal areas - the stash is looked up, the coderef found, the=20
coderef executed and the results returned.

In the foreach example you are giving, the foreach processor looks up in th=
e=20
stash and finds a single code value - not a list value.  An iterator is set=
up=20
on the single value.  The foreach loop then iterates, finds the first value=
=20
which is a coderef, executes it, and uses the return value as the results o=
f=20
the first (and only) iteration.

This is how it works in CGI::Ex::Template, and I'm pretty sure it is the sa=
me=20
in Template::Toolkit.  Therefore you can't really use a macro to return a=20
list to a foreach block - although you could still do:

[% macro_list.2 %]

Paul Seamons


On Tuesday 05 December 2006 3:42 pm, Francesc Rom=E0 i Frigol=E9 wrote:
> Hello list,
>
> I'm new at TT. After RTFMing i've tried to do macros that manipulate
> lists and I've realized that I haven't understood how TT macros work.
> Could you please tell me why the following constructs that look
> equivalent to me behave so differently? What have I missed?
>
>
> 1) MACRO CAN'T RETURN A LIST:  I can't use a macro that expands to a
> list in a loop. see this simple example:
>
> [% list =3D [1..5] %]
> [%
>   MACRO macro_list BLOCK;
>      list;
>    END;
> %]
>
> list:
> [%
>   FOREACH element IN list ;
>     "$element ";
>   END;
> %]
>
> macro:
> [%
>   FOREACH element IN macro_list ;
>     "$element ";
>   END;
> %]
>
>
> Which gives the following output ( I would expect the same output in
> both cases )
>
> list:
> 1 2 3 4 5
>
> macro:
> ARRAY(0x843900c)
>
>
>
>
> 2) LIST MANIPULATION: straightforward list manipulation is ignored
> inside MACRO, i need to resort to Virtual Methods. example list =3D [
> 1..5] doesn't work, I have to do list.splice + list.push inside a loop
> like shown below:
>
> [%
>    MACRO initialize_push BLOCK;
>      devnull =3D list.splice(0);
>      FOREACH num IN [ 10..15 ] ;
>         list.push(num) ;
>      END;
>    END;
> %]
> [%
>    MACRO initialize_simple BLOCK;
>      list =3D [ 6..10 ] ;
>    END;
> %]
> [%
>    MACRO show_list BLOCK;
>       FOREACH element IN list;
>     "$element ";
>       END;
>    END;
> %]
> manual initialization
> [%
>    list =3D [ 1..5 ];
>    show_list;
> %]
> initialization with macro
> [%
>    initialize_simple;
>    show_list;
> %]
> initialization with push macro
> [%
>    initialize_push;
>
>    show_list;
> %]
>
> The output of this macro is
>
> manual initialization
> 1 2 3 4 5
> initialization with macro
> 1 2 3 4 5
> initialization with push macro
> 10 11 12 13 14 15
>
> And I had expected
>
> manual initialization
>  1 2 3 4 5
>  initialization with macro
> 6 7 8 9 10
>  initialization with push macro
>  10 11 12 13 14 15
>
>
>
> Thank you very much for your time,
> Francesc
>
> _______________________________________________
> templates mailing list
> templates@template-toolkit.org
> http://lists.template-toolkit.org/mailman/listinfo/templates