[Templates-cvs] cvs commit: TT3/lib/Template Source.pm
cvs@template-toolkit.org
cvs@template-toolkit.org
Thu, 25 Mar 2004 14:28:16 +0000
cvs 04/03/25 14:28:15
Modified: lib/Template Source.pm
Log:
* enhanced component() method to build components out of existing
subroutine references and also do the right thing if passed an
existing component reference
Revision Changes Path
1.2 +89 -40 TT3/lib/Template/Source.pm
Index: Source.pm
===================================================================
RCS file: /template-toolkit/TT3/lib/Template/Source.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Source.pm 2004/03/23 14:57:58 1.1
+++ Source.pm 2004/03/25 14:28:15 1.2
@@ -17,7 +17,7 @@
# modify it under the same terms as Perl itself.
#
# REVISION
-# $Id: Source.pm,v 1.1 2004/03/23 14:57:58 abw Exp $
+# $Id: Source.pm,v 1.2 2004/03/25 14:28:15 abw Exp $
#
#========================================================================
@@ -25,15 +25,19 @@
use strict;
use warnings;
+use Template::Component;
use Template::Base;
use base qw( Template::Base );
-use vars qw( $VERSION $DEBUG $ERROR $LIFE );
+use vars qw( $VERSION $DEBUG $ERROR $LIFE $COMPONENT );
-$VERSION = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/);
-$DEBUG = 0 unless defined $DEBUG;
-$ERROR = '';
-$LIFE = 60; # default lifetime is 60 seconds before re-stat
+$VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);
+$DEBUG = 0 unless defined $DEBUG;
+$ERROR = '';
+$COMPONENT = 'Template::Component';
+#$THROW = 'source';
+$LIFE = 60; # default lifetime is 60 seconds before re-stat
+# TODO: make component an option
#------------------------------------------------------------------------
# init()
@@ -195,7 +199,8 @@
return $self->{ text } ||= do {
my $provider = $args->{ provider } || $self->{ provider }
- || return $self->error('no provider defined');
+ || return $self->error('no provider to load template text: ',
+ $self->{ id });
$provider->load($self->{ load })
|| return $self->error($provider->error());
@@ -251,18 +256,58 @@
my $code = $self->{ code } || $self->code(@_) || return;
my $component;
- # trap any errors thrown via die()
- local $SIG{__WARN__} = sub { die(@_) };
-
- # evaluate Perl code to generate component object
- $component = eval $$code;
-
- # check for errors
- return $self->error("failed to create component: $@")
- if $@ || ! $component;
+ if (UNIVERSAL::isa($code, 'SCALAR')) {
+ # this is the usual case where $code is a reference to a scalar
+ # containing the Perl code compiled from the template source.
+ # we first set up a hook to throw warnings as errors and then
+ # eval the Perl code to (hopefull) generate a live component.
+
+ $self->debug("evaluating component source code\n") if $self->{ DEBUG };
+
+ # trap any errors thrown via die()
+ local $SIG{__WARN__} = \&death;
+
+ # evaluate Perl code to generate component object
+ $component = eval $$code
+ || return $self->error("failed to evaluate component source code: $@");
+ }
+ elsif (UNIVERSAL::isa($code, 'CODE')) {
+ # looks like we've already got a code reference, probably
+ # provided as an anonymous subroutine, but we must delete
+ # it from the source and create a dummy value instead to
+ # indicate that the source code (i.e. Perl code) isn't
+ # available any more (or ever in this case).
+
+ $self->debug("creating component code wrapper\n") if $self->{ DEBUG };
+
+ my $dummy_code = '';
+ $self->{ code } = \$dummy_code;
+
+ $component = $COMPONENT->new({
+ name => $self->{ name },
+ path => $self->{ path },
+ time => $self->{ time },
+ body => $code,
+ options => $self->{ options },
+ }) || return $self->error($COMPONENT->error());
+ }
+ elsif (UNIVERSAL::isa($code, $COMPONENT)) {
+ # looks like we've already got a component, but we also
+ # need to blank out the code reference to avoid circular
+ # references when we bind the source to the component below
+
+ $self->debug("using existing component\n") if $self->{ DEBUG };
+
+ $component = $code;
+ $code = '';
+ $self->{ code } = \$code;
+ }
+ else {
+ return $self->error("invalid source code type: $code\n");
+ }
# set source in component
- # $component->source($self);
+ $component->source($self);
$self->debug("created component: $component\n") if $self->{ DEBUG };
@@ -301,42 +346,26 @@
if $self->{ DEBUG };
return 1;
}
-
- # TODO: should we just return OK, or not?
+ # if we haven't got a provider then we assume we're fresh
my $provider = $self->{ provider }
- || return $self->error('no provider defined');
+ || return 1;
- my $time = $provider->time($self->{ load });
+ my $time = $provider->time($self->{ load })
+ || return 1;
- return $self->error($provider->error())
- unless defined $time;
-
return $time > $self->{ time } ? 0 : 1;
}
#------------------------------------------------------------------------
-# strip()
-#
-# Delete anything non-essential and potentially large (e.g. text and
-# code) to reduce the memory footprint of the object as much as possible
-# to make it more suitable for caching in memory.
-#------------------------------------------------------------------------
-
-sub strip {
- my $self = shift;
- delete @$self{ qw( text code ) };
- return $self;
-}
-
-
-#------------------------------------------------------------------------
# stub()
#
# Return a reference to a hash array containing the minimal set of data
# items (id and time) required to identifying the source to a cache,
# store or other template storage mechanism.
+# TODO: don't think we need this any more - templates only stored id
+# in srcmap now
#------------------------------------------------------------------------
sub stub {
@@ -348,6 +377,21 @@
}
+#------------------------------------------------------------------------
+# death(@_)
+#
+# Simple handler which is used to catch compilation warnings and upgrade
+# then to errors, thrown via die.
+#------------------------------------------------------------------------
+
+sub death {
+ die @_;
+}
+
+
+
+
+
1;
__END__
@@ -379,6 +423,11 @@
the source of a template, typically a file, as provided by a
Template::Provider.
+TODO: the code is shifting a little and the docs are lagging behind.
+Most of what is written below should be accurate, but I haven't done
+a final sweep. Some recent changes in component() method haven't been
+documented (like 'code' being a subroutine ref, or existing component).
+
=head1 METHODS
=head2 new()
@@ -533,7 +582,7 @@
=head1 VERSION
-$Revision: 1.1 $
+$Revision: 1.2 $
=head1 COPYRIGHT