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   339 use strict; use utf8; use warnings FATAL => 'all';
  98     98   83  
  98     98   2029  
  98         278  
  98         88  
  98         310  
  98         1741  
  98         86  
  98         2663  
3 98     98   303 use parent 'DTL::Fast::Replacer';
  98         99  
  98         322  
4              
5 98     98   4662 use Scalar::Util qw(looks_like_number);
  98         111  
  98         3929  
6 98     98   32501 use DTL::Fast::FilterManager;
  98         132  
  98         2537  
7 98     98   34009 use DTL::Fast::Utils qw(as_bool);
  98         209  
  98         7138  
8 98     98   540 use DTL::Fast::Template;
  98         108  
  98         62410  
9              
10             sub new
11             {
12 1773     1773 0 3222 my( $proto, $variable, %kwargs ) = @_;
13              
14 1773   33     5091 $proto = ref $proto || $proto;
15            
16 1773         6700 $variable =~ s/(^\s+|\s+$)//gsi;
17 1773         4948 my @filters = split /\s*\|+\s*/, $variable;
18            
19 1773         2085 my $variable_name = shift @filters;
20            
21 1773 100 100     4790 if(
22             $kwargs{'replacement'}
23             and my $replacement = $kwargs{'replacement'}->get_replacement($variable_name)
24             )
25             {
26 7         12 $variable_name = $replacement->{'original'}; # got stored string
27             }
28            
29 1773         1563 my @variable;
30 1773         1460 my $static = 0;
31 1773         1306 my $sign = 1;
32 1773         3597 my $undef = 0;
33            
34 1773 100       2953 if( $variable_name =~ s/^\-// )
35             {
36 2         3 $sign = -1;
37             }
38            
39 1773 100 100     9968 if(
    100          
    100          
40             $variable_name =~ /^(?
41             )
42             {
43 299         636 @variable = ($2);
44 299         273 $static = 1;
45 299         294 $sign = 1;
46             }
47             elsif(
48             $variable_name eq 'undef'
49             or $variable_name eq 'None' # python compatibility
50             )
51             {
52 67         63 $static = 1;
53 67         67 $sign = 1;
54 67         56 $undef = 1;
55 67         98 @variable = (undef);
56             }
57             elsif( looks_like_number($variable_name) )
58             {
59 368         637 @variable = ($variable_name);
60 368         395 $static = 1;
61             }
62             else
63             {
64 1039 100       2150 if ( $variable_name =~ /[^\w\-\.]/)
65             {
66 1         13 die $proto->get_parse_error(
67             "variable `$variable_name` contains incorrect symbols (not /alphanumeric/-/_/./ )"
68             , 'Possible reasons' => <<'_EOM_'
69             typo in variable name
70             typo in logical operator `=` instead of `==`, for example
71             _EOM_
72             );
73             }
74 1038         2060 @variable = split /\.+/, $variable_name;
75             }
76            
77             my $self = $proto->SUPER::new(
78             'variable' => [@variable]
79             , 'original' => $variable
80             , 'direct_read' => ( scalar @variable == 1 )
81             , 'sign' => $sign
82             , 'undef' => $undef
83             , 'static' => $static
84 1772         8207 , 'filter_manager' => DTL::Fast::FilterManager->new('replacement' => $kwargs{'replacement'})
85             );
86              
87 1772 100       3808 if( scalar @filters )
88             {
89 463         1206 $self->{'filter_manager'}->add_filters(\@filters);
90             }
91              
92 1771         5371 return $self;
93             }
94              
95 1     1 0 4 sub add_filter{ return shift->{'filter_manager'}->add_filter(shift); }
96              
97             sub render
98             {
99 6313     6313 0 5635 my( $self, $context, $global_safe ) = @_;
100            
101 6313         4285 my $value = undef;
102            
103 6313 100       9458 if( not $self->{'undef'} )
104             {
105             $value = $self->{'static'}
106             ? $self->{'variable'}->[0]
107             : $self->{'direct_read'}
108             ? $context->{'ns'}->[-1]->{$self->{'variable'}->[0]}
109 6195 100       13134 : $context->get($self->{'variable'}, $self);
    100          
110            
111 6191         10476 while (ref $value eq 'CODE')
112             {
113 1         2 $value = $value->();
114             }
115             }
116            
117 6309 100 66     10702 if (
118             $self->{'sign'} == -1
119             and looks_like_number $value
120             )
121             {
122 2         2 $value = -$value;
123             }
124            
125             $value = $self->{'filter_manager'}->filter($value, $context)
126 6309 100       9702 if $self->{'filter_manager'}->{'filters_number'};
127            
128             return (
129             not $global_safe
130 6303 100 100     26957 and not $self->{'filter_manager'}->{'safe'}
131             )
132             ? DTL::Fast::html_protect($value)
133             : $value;
134             }
135              
136             our $BOOL_PROCESSORS = {
137             'SCALAR' => sub
138             {
139             my( $value ) = @_;
140             return $$value;
141             }
142             , 'HASH' => sub
143             {
144             my( $value ) = @_;
145             return scalar keys(%$value);
146             }
147             , 'ARRAY' => sub
148             {
149             my( $value ) = @_;
150             return scalar @$value;
151             }
152             };
153              
154             1;