1#================================================================= -*-Perl-*- 2# 3# Template::Namespace::Constants 4# 5# DESCRIPTION 6# Plugin compiler module for performing constant folding at compile time 7# on variables in a particular namespace. 8# 9# AUTHOR 10# Andy Wardley <abw@wardley.org> 11# 12# COPYRIGHT 13# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. 14# 15# This module is free software; you can redistribute it and/or 16# modify it under the same terms as Perl itself. 17# 18#============================================================================ 19 20package Template::Namespace::Constants; 21 22use strict; 23use warnings; 24use base 'Template::Base'; 25use Template::Config; 26use Template::Directive; 27use Template::Exception; 28 29our $VERSION = 1.27; 30our $DEBUG = 0 unless defined $DEBUG; 31 32 33sub _init { 34 my ($self, $config) = @_; 35 $self->{ STASH } = Template::Config->stash($config) 36 || return $self->error(Template::Config->error()); 37 return $self; 38} 39 40 41 42#------------------------------------------------------------------------ 43# ident(\@ident) foo.bar(baz) 44#------------------------------------------------------------------------ 45 46sub ident { 47 my ($self, $ident) = @_; 48 my @save = @$ident; 49 50 # discard first node indicating constants namespace 51 splice(@$ident, 0, 2); 52 53 my $nelems = @$ident / 2; 54 my ($e, $result); 55 local $" = ', '; 56 57 print STDERR "constant ident [ @$ident ] " if $DEBUG; 58 59 foreach $e (0..$nelems-1) { 60 # node name must be a constant 61 unless ($ident->[$e * 2] =~ s/^'(.+)'$/$1/s) { 62 $self->DEBUG(" * deferred (non-constant item: ", $ident->[$e * 2], ")\n") 63 if $DEBUG; 64 return Template::Directive->ident(\@save); 65 } 66 67 # if args is non-zero then it must be eval'ed 68 if ($ident->[$e * 2 + 1]) { 69 my $args = $ident->[$e * 2 + 1]; 70 my $comp = eval "$args"; 71 if ($@) { 72 $self->DEBUG(" * deferred (non-constant args: $args)\n") if $DEBUG; 73 return Template::Directive->ident(\@save); 74 } 75 $self->DEBUG("($args) ") if $comp && $DEBUG; 76 $ident->[$e * 2 + 1] = $comp; 77 } 78 } 79 80 81 $result = $self->{ STASH }->get($ident); 82 83 if (! length $result || ref $result) { 84 my $reason = length $result ? 'reference' : 'no result'; 85 $self->DEBUG(" * deferred ($reason)\n") if $DEBUG; 86 return Template::Directive->ident(\@save); 87 } 88 89 $result =~ s/'/\\'/g; 90 91 $self->DEBUG(" * resolved => '$result'\n") if $DEBUG; 92 93 return "'$result'"; 94} 95 961; 97 98__END__ 99 100=head1 NAME 101 102Template::Namespace::Constants - Compile time constant folding 103 104=head1 SYNOPSIS 105 106 # easy way to define constants 107 use Template; 108 109 my $tt = Template->new({ 110 CONSTANTS => { 111 pi => 3.14, 112 e => 2.718, 113 }, 114 }); 115 116 # nitty-gritty, hands-dirty way 117 use Template::Namespace::Constants; 118 119 my $tt = Template->new({ 120 NAMESPACE => { 121 constants => Template::Namespace::Constants->new({ 122 pi => 3.14, 123 e => 2.718, 124 }, 125 }, 126 }); 127 128=head1 DESCRIPTION 129 130The C<Template::Namespace::Constants> module implements a namespace handler 131which is plugged into the C<Template::Directive> compiler module. This then 132performs compile time constant folding of variables in a particular namespace. 133 134=head1 METHODS 135 136=head2 new(\%constants) 137 138The new() constructor method creates and returns a reference to a new 139Template::Namespace::Constants object. This creates an internal stash 140to store the constant variable definitions passed as arguments. 141 142 my $handler = Template::Namespace::Constants->new({ 143 pi => 3.14, 144 e => 2.718, 145 }); 146 147=head2 ident(\@ident) 148 149Method called to resolve a variable identifier into a compiled form. In this 150case, the method fetches the corresponding constant value from its internal 151stash and returns it. 152 153=head1 AUTHOR 154 155Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/> 156 157=head1 COPYRIGHT 158 159Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. 160 161This module is free software; you can redistribute it and/or 162modify it under the same terms as Perl itself. 163 164=head1 SEE ALSO 165 166L<Template::Directive> 167 168=cut 169 170# Local Variables: 171# mode: perl 172# perl-indent-level: 4 173# indent-tabs-mode: nil 174# End: 175# 176# vim: expandtab shiftwidth=4: 177