File Coverage

blib/lib/DTL/Fast/Variable.pm
Criterion Covered Total %
statement 65 65 100.0
branch 26 26 100.0
condition 12 15 80.0
subroutine 11 11 100.0
pod 0 3 0.0
total 114 120 95.0


line stmt bran cond sub pod time code
1             package DTL::Fast::Variable;
2 98     98   537 use strict;
  98         180  
  98         2154  
3 98     98   399 use utf8;
  98         172  
  98         370  
4 98     98   1945 use warnings FATAL => 'all';
  98         167  
  98         2837  
5 98     98   465 use parent 'DTL::Fast::Replacer';
  98         191  
  98         1025  
6              
7 98     98   5416 use Scalar::Util qw(looks_like_number);
  98         807  
  98         3926  
8 98     98   29697 use DTL::Fast::FilterManager;
  98         225  
  98         2537  
9 98     98   30458 use DTL::Fast::Utils qw(as_bool);
  98         333  
  98         6793  
10 98     98   672 use DTL::Fast::Template;
  98         192  
  98         62185  
11              
12             sub new
13             {
14 1773     1773 0 4834 my ( $proto, $variable, %kwargs ) = @_;
15              
16 1773   33     6531 $proto = ref $proto || $proto;
17              
18 1773         6876 $variable =~ s/(^\s+|\s+$)//gsi;
19 1773         6166 my @filters = split /\s*\|+\s*/, $variable;
20              
21 1773         3313 my $variable_name = shift @filters;
22              
23 1773 100 100     6197 if (
24             $kwargs{replacement}
25             and my $replacement = $kwargs{replacement}->get_replacement($variable_name)
26             )
27             {
28 7         17 $variable_name = $replacement->{original}; # got stored string
29             }
30              
31 1773         2671 my @variable;
32 1773         2637 my $static = 0;
33 1773         2480 my $sign = 1;
34 1773         3429 my $undef = 0;
35              
36 1773 100       4202 if ($variable_name =~ s/^\-//)
37             {
38 2         5 $sign = - 1;
39             }
40              
41 1773 100 100     11650 if (
    100          
    100          
42             $variable_name =~ /^(?
43             )
44             {
45 299         847 @variable = ($2);
46 299         586 $static = 1;
47 299         464 $sign = 1;
48             }
49             elsif (
50             $variable_name eq 'undef'
51             or $variable_name eq 'None' # python compatibility
52             )
53             {
54 67         109 $static = 1;
55 67         99 $sign = 1;
56 67         98 $undef = 1;
57 67         128 @variable = (undef);
58             }
59             elsif (looks_like_number($variable_name))
60             {
61 368         886 @variable = ($variable_name);
62 368         622 $static = 1;
63             }
64             else
65             {
66 1039 100       2879 if ($variable_name =~ /[^\w\-\.]/)
67             {
68 1         14 die $proto->get_parse_error(
69             "variable `$variable_name` contains incorrect symbols (not /alphanumeric/-/_/./ )"
70             , 'Possible reasons' => <<'_EOM_'
71             typo in variable name
72             typo in logical operator `=` instead of `==`, for example
73             _EOM_
74             );
75             }
76 1038         2660 @variable = split /\.+/, $variable_name;
77             }
78              
79             my $self = $proto->SUPER::new(
80             variable => [ @variable ]
81             , original => $variable
82             , direct_read => ( scalar @variable == 1 )
83             , sign => $sign
84             , undef => $undef
85             , static => $static
86             , filter_manager => DTL::Fast::FilterManager->new(replacement => $kwargs{replacement})
87 1772         8876 );
88              
89 1772 100       5003 if (scalar @filters)
90             {
91 463         1472 $self->{filter_manager}->add_filters(\@filters);
92             }
93              
94 1771         6226 return $self;
95             }
96              
97 1     1 0 5 sub add_filter { return shift->{filter_manager}->add_filter(shift); }
98              
99             sub render
100             {
101 6303     6303 0 10832 my ( $self, $context, $global_safe ) = @_;
102              
103 6303         9115 my $value = undef;
104              
105 6303 100       13867 if (not $self->{undef})
106             {
107             $value = $self->{static}
108             ? $self->{variable}->[0]
109             : $self->{direct_read}
110             ? $context->{ns}->[- 1]->{$self->{variable}->[0]}
111 6185 100       16938 : $context->get($self->{variable}, $self);
    100          
112              
113 6181         14632 while (ref $value eq 'CODE')
114             {
115 1         4 $value = $value->();
116             }
117             }
118              
119 6299 100 66     15550 if (
120             $self->{sign} == - 1
121             and looks_like_number $value
122             )
123             {
124 2         3 $value = - $value;
125             }
126              
127             $value = $self->{filter_manager}->filter($value, $context)
128 6299 100       13981 if ($self->{filter_manager}->{filters_number});
129              
130             return (
131             not $global_safe
132             and not $self->{filter_manager}->{safe}
133             )
134 6293 100 100     31072 ? DTL::Fast::html_protect($value)
135             : $value;
136             }
137              
138             our $BOOL_PROCESSORS = {
139             SCALAR => sub
140             {
141             my ( $value ) = @_;
142             return $$value;
143             }
144             , HASH => sub
145             {
146             my ( $value ) = @_;
147             return scalar keys(%$value);
148             }
149             , ARRAY => sub
150             {
151             my ( $value ) = @_;
152             return scalar @$value;
153             }
154             };
155              
156             1;