So I finally pushed through and finished dealing with item vs list vs smart 
context in Template::Alloy.  The solution was the adding of a new 
configuration item called CALL_CONTEXT which can be passed to new or set 
using the CONFIG directive.  I've then borrowed the Perl 6 list and item 
context specifiers @() and $() respectively.  This is a very lightweight 
solution that works for top level functions or chained functions and methods 
and could be somewhat easily adopted in TT2.

This is now implemented in Template::Alloy 1.012 for anybody that would like 
to play with it.  Template::Alloy::XS doesn't yet handle the CALL_CONTEXT 
directive - but it will soon.

The following is the documentation in Template::Alloy that explains what I'm 
talking about.


CALL_CONTEXT

Can be one of 'item', 'list', or 'smart'. The default type
is 'smart'. The CALL_CONTEXT configuration specifies in what
Perl context coderefs and methods used in the processed
templates will be called. TT historically has avoided the
distinction of item (scalar) vs list context. To avoid
worrying about this, TT introduced 'smart' context. The
"@()" and "$()" context specifiers make it easier to use
CALL_CONTEXT in some situations.

The following table shows the relationship between the
various contexts:

       return values      smart context   list context    item context
       -------------      -------------   ------------    ------------
    A   'foo'              'foo'           ['foo']         'foo'
    B   undef              undef           [undef]         undef
    C   (no return value)  undef           []              undef
    D   (7)                7               [7]             7
    E   (7,8,9)            [7,8,9]         [7,8,9]         9
    F   @a = (7)           7               [7]             1
    G   @a = (7,8,9)       [7,8,9]         [7,8,9]         3
    H   ({b=>"c"})         {b=>"c"}        [{b=>"c"}]      {b=>"c"}
    I   ([1])              [1]             [[1]]           [1]
    J   ([1],[2])          [[1],[2]]       [[1],[2]]       [2]
    K   [7,8,9]            [7,8,9]         [[7,8,9]]       [7,8,9]
    L   (undef, "foo")     die "foo"       [undef, "foo"]  "foo"
    M   wantarray?1:0      1               1               0

Cases F, H, I and M are common sticking points of the the
smart context in TT2. Note that list context always returns
an arrayref from a method or function call. Smart context
can give confusing results sometimes, especially the I and J
cases. Case L for smart match is very surprising.

The list and item context provide another feature for method
calls. In smart context, TT will look for a hash key in the
object by the same name as the method, if a method by that
name doesn't exist. In item and list context Alloy will die
if a method by that name cannot be found.

The CALL_CONTEXT configuration item can be passed to new or
it may also be set during runtime using the CONFIG
directive. The following method call would be in list
context:

    [% CONFIG CALL_CONTEXT => 'list';
       results = my_obj.get_results;
       CONFIG CALL_CONTEXT => 'smart'
    %]

Note that we needed to restore CALL_CONTEXT to the default
'smart' value. Template::Alloy has added the "@()" (list)
and the "$()" (item) context specifiers. The previous
example could be written as:

    [% results = @( my_obj.get_results ) %]

To call that same method in item (scalar) context you would
do the following:

    [% results = $( my_obj.get_results ) %]

The "@()" and "$()" operators are based on the Perl 6
counterpart.

_______________________________________________
templates mailing list
[email protected]
http://mail.template-toolkit.org/mailman/listinfo/templates

Reply via email to