Template::Alloy::Operator(3pm) | User Contributed Perl Documentation | Template::Alloy::Operator(3pm) |
Template::Alloy::Operator - Operator role.
The Template::Alloy::Operator role provides the regexes necessary for Template::Alloy::Parse to parse operators and place them in their appropriate precedence. It also provides the play_operator method which is used by Template::Alloy::Play and Template::Alloy::Compile for playing out the stored operator ASTs.
[undef, '+', 1, 2]
Essentially, all operators are stored in RPN notation with a leading "undef" to disambiguate operators in a normal Alloy expression AST.
See Template::Alloy for more details.
The following operators are available in Template::Alloy. Except where noted these are the same operators available in TT. They are listed in the order of their precedence (the higher the precedence the tighter it binds).
my $obj->process(\$content, {a => {b => [0, {c => [34, 57]}]}}, \$output); [% a.b.1.c.0 %] => 34
Note: on access to hashrefs, any hash keys that match the sub key name will be used before a virtual method of the same name. For example if a passed hash contained pair with a keyname "defined" and a value of "2", then any calls to hash.defined(another_keyname) would always return 2 rather than using the vmethod named "defined." To get around this limitation use the "|" operator (listed next). Also - on objects the "." will always try and call the method by that name. To always call the vmethod - use "|".
The pipe character is similar to TT2 in that it can be used in place of a directive as an alias for FILTER. It similar to TT3 in that it can be used for virtual method access. This duality is one source of difference between Template::Alloy and TT2 compatibility. Templates that have directives that end with a variable name that then use the "|" directive to apply a filter will be broken as the "|" will be applied to the variable name.
The following two cases will do the same thing.
[% foo | html %] [% foo FILTER html %]
Though they do the same thing, internally, foo|html is stored as a single variable while "foo FILTER html" is stored as the variable foo which is then passed to the FILTER html.
A TT2 sample that would break in Template::Alloy or TT3 is:
[% PROCESS foo a = b | html %]
Under TT2 the content returned by "PROCESS foo a = b" would all be passed to the html filter. Under Template::Alloy and TT3, b would be passed to the html filter before assigning it to the variable "a" before the template foo was processed.
A simple fix is to do any of the following:
[% PROCESS foo a = b FILTER html %] [% | html %][% PROCESS foo a = b %][% END %] [% FILTER html %][% PROCESS foo a = b %][% END %]
This shouldn't be too much hardship and offers the great return of disambiguating virtual method access.
[% f = 7 ; foo = \f ; f = 8 ; foo %] => 8 [% foo = \f.g.h.i.j.k; f.g.h.i.j.k = 7; foo %] => 7 [% f = "abcd"; foo = \f.replace("ab", "-AB-") ; foo %] => -AB-cd [% f = "abcd"; foo = \f.replace("bc") ; foo("-BC-") %] => a-BC-d [% f = "abcd"; foo = \f.replace ; foo("cd", "-CD-") %] => ab-CD-
[% ++a %][% ++a %] => 12 [% a++ %][% a++ %] => 01 [% --a %][% --a %] => -1-2 [% a-- %][% a-- %] => 0-1
[% 2 ** 3 %] => 8
[% a = 1 ; b = -a ; b %] => -1
[% 10 / 4 %] => 2.5 [% 10 div 4 %] => 2
[% 15 % 8 %] => 7
[% "a" ~ "b" %] => ab
The HTML::Template syntaxes default V2EQUALS to 0 which means that it will test for numeric equality just as you would normally expect.
In either case - you should always use "eq" when you mean "eq". The V2EQUALS will most likely eventually default to 0.
The HTML::Template syntaxes default V2EQUALS to 0 which means that it will test for numeric non-equality just as you would normally expect.
In either case - you should always use "ne" when you mean "ne". The V2EQUALS will most likely eventually default to 0.
[% 2 && 3 && 4 %] => 4
[% 0 || '' || 7 %] => 7
Note: perl is left associative on this operator - but it doesn't matter because || has its own precedence level. Setting it to right allows for Alloy to short circuit earlier in the expression optree (left is (((1,2), 3), 4) while right is (1, (2, (3, 4))).
[% foo // bar %]
[% t = [1 .. 5] %] => variable t contains an array with 1,2,3,4, and 5
It is possible to place multiple ranges in the same [] constructor. This is not available in TT.
[% t = [1..3, 6..8] %] => variable t contains an array with 1,2,3,6,7,8
The .. operator is the only operator that returns a list of items.
[% 1 ? 2 : 3 %] => 2 [% 0 ? 2 : 3 %] => 3
[% a = 2 %][% a += 3 %] --- [% a %] => --- 5 # is handled by SET [% a = 2 %][% (a += 3) %] --- [% a %] => 5 --- 5
[% a = 1 %] --- [% a %] => --- 1 # is handled by SET [% (a = 1) %] --- [% a %] => 1 --- 1
[% foo = ->{ "Hi" } %][% foo %] => Hi [% foo = ->{ this.repeat(2) } %][% foo("Hi") %] => HiHi [% foo = ->(n){ n.repeat(2) } %][% foo("Hi") %] => HiHi [% foo = ->(a,b){ a; "|"; b } %][% foo(2,3) %] => 2|3 [% [0..10].grep(->{ this % 2 }).join %] => 1 3 5 7 9 [% ['a'..'c'].map(->{ this.upper }).join %] => A B C [% [1,2,3].sort(->(a,b){ b <=> a }).join %] prints 3 2 1 [% c = [{k => "wow"}, {k => "wee"}, {k => "a"}] %] [% c.sort(->(a,b){ a.k cmp b.k }).map(->{this.k}).join %] => a wee wow
Note: Care should be used when attempting to sort large lists. The mini-language of Template::Alloy is a interpreted language running in Perl which is an interpreted language. There are likely to be performance issues when trying to do low level functions such as sort on large lists.
The RETURN directive and return item, list, and hash vmethods can be used to return more interesting values from a MACRO.
[% a = ->(n){ [1..n].return } %] [% a(3).join %] => 1 2 3 [% a(10).join %] => 1 2 3 4 5 6 7 8 9 10
The Schwartzian transform is now possible in Template::Alloy (somebody somewhere is rolling over in their grave).
[%- qw(Z a b D y M) .map(->{ [this.lc, this].return }) .sort(->(a,b){a.0 cmp b.0}) .map(->{this.1}) .join %] => a b D M y Z
Paul Seamons <paul@seamons.com>
This module may be distributed under the same terms as Perl itself.
2022-10-16 | perl v5.36.0 |