On Nov 16, 2006, at 3:08 PM, html-template-users- 
[EMAIL PROTECTED] wrote:

>
> Date: Wed, 15 Nov 2006 15:59:44 -0500 (EST)
> From: Sam Tregar <[EMAIL PROTECTED]>
> Subject: Re: [htmltmpl] The sf.net Subversion Repository and the
>       Phalanx One
> To: Shlomi Fish <[EMAIL PROTECTED]>
> Cc: html-template-users@lists.sourceforge.net
> Message-ID: <[EMAIL PROTECTED]>
> Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed
>
> On Wed, 15 Nov 2006, Shlomi Fish wrote:
>
>> A question if I may. Why weren't the tests and other changes that
>> were done to the Phalanx work on HTML-Template:
>>
>> * http://svn.perl.org/phalanx/HTML-Template/
>> * http://hew.ca/yapc/phalanx/slides/TABLE_OF_CONTENTS.html
>>
>> Integrated into the mainline HTML-Template at:
>>
>> https://svn.sourceforge.net/svnroot/html-template/
>
> Lack of motivation, I suppose.  As far as I know they never found or
> fixed a bug in HTML::Template.  At this point their repo is out of
> date and it would be a painful process to do the merge.
>



Here is the summary of the Perl Seminar NY Phalanx project work on  
HTML::Template which we submitted to Sam Tregar on June 11, 2005.  It  
was written in POD, so you might want to copy-and-paste it into a  
file and run perldoc on it.

For good measure, I've placed a tarball of the final version of our  
work on HTML::Template here:  http://thenceforward.net/perl/misc/HTML- 
Template-2.701.tar.gz

(You can get a tarball of our work on Text::Template in the same  
directory.)

Sam, we'd still welcome feedback.

Jim Keenan


=head1 SUMMARY

This document summarizes work done on Perl module  HTML::Template by
members of Perl Seminar New York as part of the Phalanx project.  We
discuss what we were able to accomplish as of June 11, 2005, as well as
what we were not able to do, what might remain to be done,
or what we think should be done.

=head1 Definitions

''We'' equals the Perl Seminar NY Phalanx hoplites who have contributed
to revisions as of the above date:  David H Adler (dha), Jim Keenan
(jkeenan), Marc Prewitt (mprewitt) and Alex Gill (alexgill).

''You'' equals Sam Tregar.

=head1 Diffs

In order to generate meaningful diff files, we increased C<$VERSION> to
2.701.  All diffs were generated against version 2.7 as taken from CPAN.
(We made no reference to the Sourceforge version of the distribution.)

We present diffs in three different formats, each of which has its
merits:

=over 4

=item svn diff

Diff files generated by Subversion's C<svn diff> command run
individually on each of the two files which have undergone revision so
far:

     MANIFEST
     Template.pm

Each diff file so generated will end with suffix C<.diff>.

=item difftidy

We run each of the revised files listed above through F<perltidy> and
then run the results through the system's F<diff> program.  This may --
or may not -- help to reduce spurious differences caused by, I<e.g.,>
elimination of trailing whitespace.  Each such diff file will end with
suffix C<.ovn>.

=item diffcode and diffpod

We wrote a Perl script based on the work of Perl Seminar NY member
Glenn Maciag
which produces one diff file for differences in code (F<diffcode>) and a
separate diff file for differences in documentation written in POD
format (F<diffpod>).  We found this useful for modules where code and
POD are interleaved because the content is more focused yet the line
numbers are preserved.

=back

Pick and choose!

=head1 Code Coverage

The Perlsemny Phalanx project used Paul Johnson's Devel::Cover module to
measure the extent to which HTML::Template's test suite actually tested
its code.  The following table shows HTML::Template's code coverage as
measured at two different points in time:  just before we began our
work, and where we stood on the above date after two joint hacking
sessions.  ''Version 175'' refers to entry 175 in the Phalanx Subversion
repository and is, for all practical purposes, equivalent to the current
version of HTML::Template found on CPAN, i.e., version 2.7.  Coverage
results are shown for statement, branch, condition and subroutine
coverage.

   Version 175
     File                     stmt    branch    cond     sub
     Template.pm              85.2      63.5    50.0    84.9

   Version 344
     File                     stmt    branch    cond     sub
     Template.pm              90.7      72.7    65.8    94.4

As the data suggest, HTML::Template already had a very high percentage
-- 85.2% -- of its statements covered before Phalanx began work on it.
However, the coverage of branches and conditions was lower, and some
subroutines were as yet completely uncovered.

As a result of Phalanx's work through early June 2005, statement
coverage was increased to over 90%, branch coverage improved to
over 72%, condition coverage increased by a quarter to over 65% and
subroutine coverage is now at more than 94%.

The major obstacle to even more improved coverage is technical:  Certain
features of HTML::Template are only available on OSes where one can
install IPC::ShareLite, Gtop, etc.  To date, we have not had access to
such a system, so features such as C<shared_cache>, C<double_cache> and
C<memory_debug> are so far untested.  However, we feel that some of what
we learned so far will be readily applicable to those features once we
have access to them.  So we can confidently expect even more
improvements in code coverage as our work continues.

=head2 A Note on POD Coverage

In the table above we present only the first four columns in a typical
Devel::Cover coverage report.  While Devel::Cover can provide POD
coverage as well, it does so only by relying on Perl extension
Pod::Coverage.  But Pod::Coverage, at least in its native format, only
reports accurately on documentation provided that the module author has
written the POD using subroutines as the titles of subsections.  In
certain cases you have done this but, like many other module authors,
you have not done this for all subroutines -- nor do we think you
necessarily should do this.  We saw no reason to rewrite the
documentation with new subsection headings simply to get a better
looking statistic out of Pod::Coverage and, in turn, Devel::Cover.
So we have not included the coverage column in the table above.

=head1 Revisions of Code

=head2 Refactoring of Code Repeated within C<new()> and  
C<_new_from_loop()>

The following code appeared in both C<new()> (beginning at 961) and
C<_new_from_loop()> (beginning at 1118):

     for (my $x = 0; $x <= $#_; $x += 2) {
       defined($_[($x + 1)]) or croak("HTML::Template->new() called  
with odd number of option parameters - should be of the form option  
=> value");
       $options->{lc($_[$x])} = $_[($x + 1)];
     }

It was refactored into a new subroutine, C<_load_supplied_options()>.
Example:

     $options = _load_supplied_options( [EMAIL PROTECTED], $options);

Here is the new subroutine:

     sub _load_supplied_options {
         my $argsref = shift;
         my $options = shift;
         for (my $x = 0; $x <= $#_; $x += 2) {
           defined($_[($x + 1)]) or croak("HTML::Template->new()  
called with odd number of option parameters - should be of the form  
option => value");
           $options->{lc($_[$x])} = $_[($x + 1)];
         }
         return $options;
     }

=head2 Additional Error-Checking in C<new()>

The documentation makes clear that the caching features can only be used
when the source of a template is a file -- not when it is a string, an
array or a filehandle.  What would happen in the current version of
HTML::Template if someone tried to activate caching when the template
source was not a file?

Experimentation showed that the program would die a horrible death.
Multiple error messages would be emitted from subroutines several levels
below C<new()>, but these error messages would not clearly point to the
problem.  For example, calling this script:

     #!/usr/local/bin/perl
     use strict;
     use warnings;
     use HTML::Template;

     my ($stemplate, $template_string);

     open my $fh, 'templates/simple.tmpl'
         or die "Couldn't open simple.tmpl for reading: $!";
     {
         local $/;
         $template_string = <$fh>;
         seek $fh, 0, 0;
     }

     $stemplate = HTML::Template->new(
         type   => 'scalarref',
         source => \$template_string,
         cache  => 1,
     );

... generated these messages:

     HTML::Template->new() : Cannot find file ''. at
     /usr/local/lib/perl5/site_perl/5.8.4/HTML/Template.pm line 1293
             HTML::Template::_cache_key('HTML::Template=HASH(0x82b3cc)')
     called at /usr/local/lib/perl5/site_perl/5.8.4/HTML/Template.pm  
line 1269
             HTML::Template::_commit_to_cache('HTML::Template=HASH 
(0x82b3cc)')
     called at /usr/local/lib/perl5/site_perl/5.8.4/HTML/Template.pm  
line 1197
             HTML::Template::_init('HTML::Template=HASH(0x82b3cc)')  
called at
     /usr/local/lib/perl5/site_perl/5.8.4/HTML/Template.pm line 1083
             HTML::Template::new('HTML::Template', 'type', 'scalarref',
     'source', 'SCALAR(0x806f00)', 'cache', 1) called at templstr.pl  
line 16

We solved this problem by adding some additional error-checking code to
the constructor which causes the program to C<croak> if the user
attempts to call for caching with a non-file source.

     # check that cache options are not used with non-cacheable  
templates
     croak "Cannot have caching when template source is not file"
       if grep { exists($options->{$_}) } qw( filehandle arrayref  
scalarref)
         and
          grep {$options->{$_}} qw( cache blind_cache file_cache  
shared_cache
                                    double_cache double_file_cache );

All tests continued to pass.  Adding this code to the constructor meant
that some error-checking code in more internal subroutines (I<e.g.,>
C<_cache_key>) could safely be eliminated, thereby increasing the
total percentage of code covered.  (From this point forward, we'll refer
to this new code as the ''double-grep test.'')

=head2 Elimination of Unnecessary Tests for Definedness of Variables

=head3 Within C<new()>

In two cases you call for the constructor to C<croak> unless a
two-part condition is met.

=over 4

=item *

Beginning at 1032:

     if (exists($options->{filename})) {
         croak("HTML::Template->new called with empty filename  
parameter!")
           unless defined $options->{filename} and length $options-> 
{filename};
     }

=item *

Beginning at 1048:

     if ($options->{file_cache}) {
       # make sure we have a file_cache_dir option
       croak("You must specify the file_cache_dir option if you want  
to use file_cache.")
         unless defined $options->{file_cache_dir} and
           length $options->{file_cache_dir};
     ...

=back

When we performed coverage analysis on these two blocks, we noted that
the case where the I<first> part of each C<unless> clause was not  
defined
was uncovered.

     line  err      %     !l  l&&!r   l&&r   expr
     ----- --- ------ ------ ------ ------   ----
     1033  ***     66      0      1     58   defined $$options 
{'filename'} and length $$options{'filename'}
     1050  ***     33      0      0      5   defined $$options 
{'file_cache_dir'} and length $$options{'file_cache_dir'}

We hypothesized that in each case the first part of the
condition was I<always> defined at this point in the program.  If so, it
would not need to be tested and could safely be eliminated.  When we
tried to pass C<undef> as a value in these two cases, the code now
represented by C<_load_supplied_options> detected an 'unbalanced
key-value pair', threw an error and caused the program to C<croak> --
I<before> either of these two blocks of code was reached.

Hence, the two blocks could be simplified to read:

=over 4

=item *

     if (exists($options->{filename})) {
         croak("HTML::Template->new called with empty filename  
parameter!")
           unless length $options->{filename};
     }

=item *

     if ($options->{file_cache}) {
       # make sure we have a file_cache_dir option
       croak("You must specify the file_cache_dir option if you want  
to use file_cache.")
         unless length $options->{file_cache_dir};
     ...

=back

All tests continued to pass after the elimination of the superfluous
tests for definedness.  Since these lines no longer include an C<and>
condition, these lines are no longer reported by Devel::Cover as
conditions -- which means the total coverage ratio for conditions
increases.

=head3 Within C<_init()>

In a way very similar to the cases just described, there are a number of
situations where you call for the C<_init()> to C<croak> unless a
two-part condition is met.

=over 4

=item *

Beginning at 1162:

     } elsif ($options->{double_file_cache}) {
       # try the normal cache, return if we have it.
       $self->_fetch_from_cache();
       return if (defined $self->{param_map} and defined $self-> 
{parse_stack});

=item *

Beginning at 1170:

       # put it in the local cache if we got it.
       $self->_commit_to_cache()
         if (defined $self->{param_map} and defined $self-> 
{parse_stack});

=item *

Beginning at 1184:

     # if we got a cache hit, return
     return if (defined $self->{param_map} and defined $self-> 
{parse_stack});

=back

In each case, the coverage reported indicated that the case where the
first part of the condition was true while the second part was false was
never being tested.
     line  err      %     !l  l&&!r   l&&r   expr
     ----- --- ------ ------ ------ ------   ----
     1165  ***      0      0      0      0   defined $$self 
{'param_map'} and defined $$self{'parse_stack'}
     1171  ***      0      0      0      0   defined $$self 
{'param_map'} and defined $$self{'parse_stack'}
     1185  ***     66     57      0      7   defined $$self 
{'param_map'} and defined $$self{'parse_stack'}

We hypothesized that if C<$self-E<gt>{param_map}> is defined,
C<$self-E<gt>{parse_stack}> must always be defined as well.  In that  
case,
we would only need the first part of the condition and could dispense
with the second.

While we don't yet understand C<param_map> and C<parse_stack> well
enough to prove this point by logic, it was empirically verified by
simplifying and testing the code.  These three blocks were rewritten as
follows:

=over 4

=item *

     } elsif ($options->{double_file_cache}) {
       # try the normal cache, return if we have it.
       $self->_fetch_from_cache();
       return if (defined $self->{param_map});

=item *

       # put it in the local cache if we got it.
       $self->_commit_to_cache()
         if (defined $self->{param_map});

=item *

     # if we got a cache hit, return
     return if (defined $self->{param_map});

=back

All tests continued to pass once these changes were made.
As was the case discussed above, since these lines no longer include
an C<and> condition, these lines are no longer reported by  
Devel::Cover as
conditions -- which means the total coverage ratio for conditions
increases.

=head2 Elimination of Unnecessary Tests for Existence of Variables

=head3 Within C<_fetch_from_cache()>

C<_fetch_from_cache()> begins as follows:

     sub _fetch_from_cache {
       my $self = shift;
       my $options = $self->{options};

       # return if there's no file here
       return unless exists($options->{filename});  # line 1214

The coverage report on branches suggested that the 'true' branch of line
1214 -- where C<$options-E<gt>{filename}> did I<not> exist -- was  
never tested.
     line  err      %   true  false   branch
     ----- --- ------ ------ ------   ------
     1214  ***     50      0      6   unless exists $$options 
{'filename'}

C<_fetch_from_cache()>, however, is always called from within C<_init()>
-- which, in turn, is always called from within C<new()> at a point
I<after> we have guaranteed that C<$options-E<gt>{filename}> not only  
exists
but is defined and of non-zero length.  Line 1214 is therefore
superfluous and may be eliminated, thereby increasing the branch
coverage ratio.

=head3 Within C<_cache_key()>

C<_cache_key()> begins:

     sub _cache_key {
         my $self = shift;
         my $options = $self->{options};

         # determine path to file unless already known
         my $filepath = $options->{filepath};
         if (not defined $filepath) {
             $filepath = $self->_find_file($options->{filename});
             confess("HTML::Template->new() : Cannot find file  
'$options->{filename}'.")
               unless defined($filepath);
             $options->{filepath} = $filepath;
         }

         # assemble pieces of the key
         my @key = ($filepath);
         push(@key, @{$options->{path}}) if $options->{path};
     ...

The branch part of the coverage report indicated that there was quite a
bit of uncovered code here.

     line  err      %   true  false   branch
     ----- --- ------ ------ ------   ------
     1291  ***     50      0     15   if (not defined $filepath)
     1293  ***      0      0      0   unless defined $filepath
     1300  ***     50     15      0   if $$options{'path'}

The L<double-grep test|additional_errorchecking_in_new__> discussed
above takes care of this coverage
deficiency.  It guarantees that, by this point in a program,
C<$options-E<gt>{filepath}> is always defined.  So quite a few lines of
code can be eliminated outright.

     sub _cache_key {
         my $self = shift;
         my $options = $self->{options};

         # assemble pieces of the key
         my @key = ($options->{filepath});
         push(@key, @{$options->{path}});
     ...

All tests again pass.  Re-running coverage analysis indicates that this
block of code is now completely covered.

=head3 Within C<_fetch_from_file_cache()>

     sub _fetch_from_file_cache {
       my $self = shift;
       my $options = $self->{options};
       return unless exists($options->{filename});
     ...

Coverage analysis indicated that the 'true' branch here -- the case
where C<$options-E<gt>{filename}> did I<not> exist -- was untested.

     line  err      %   true  false   branch
     ----- --- ------ ------ ------   ------
     1334  ***     50      0      5   unless exists $$options 
{'filename'}

Once again, the addition of the L<double-grep test| 
additional_errorchecking_in_new__> inside C<new()>
guaranteed that this C<filename> must exist by this point.  Hence,
C<_fetch_from_file_cache()> could be rewritten to begin:

     sub _fetch_from_file_cache {
       my $self = shift;
       my $options = $self->{options};
     ...

All tests continued to pass, and because an entire statement was
eliminated, both statement and branch coverage ratios increased.

=head3 Within C<_find_file()>

In C<_find_file()>, there exist these two lines of code:

     if (exists($ENV{HTML_TEMPLATE_ROOT}) and defined($ENV 
{HTML_TEMPLATE_ROOT})) {  # Line 1541
     ...
     if (exists($ENV{HTML_TEMPLATE_ROOT})) {  # Line 1556

In the first line, the test for definedness is logically sufficient.  In
the second line, a test for definedness would be better than the test
for mere existence.  So these lines can each be rewritten as:

     if (defined($ENV{HTML_TEMPLATE_ROOT})) {

All tests pass and the condition coverage ratio improves because the
first line no longer includes a condition.

=head2 Other Simplification of Code

=head3 C<param()>

We have not thoroughly plumbed the depths of C<param()>, so there is
probably quite a bit of work left there for us to do.  However, we did
manage to simplify one block of code beginning at line 2479:

       if (!scalar(@_)) {
         croak("HTML::Template->param() : Single reference arg to  
param() must be a hash-ref!  You gave me a $type.")
           unless $type eq 'HASH' or
             (ref($first) and UNIVERSAL::isa($first, 'HASH'));
         push(@_, %$first);

The C<unless> condition is visibly complex, and we have learned through
experience that complex conditions tend to contain code untested by a
module's test suite.  Sure enough, the coverage report showed for:

=over 4

=item Statements

     line  err   stmt branch   cond    sub    pod   time   code
     2479         125    100                        6445     if (! 
scalar(@_)) {
     2480  ***     48     50      0                  272       croak 
("HTML::Template->param() : Single reference arg to param() must be a  
hash-ref!  You gave me a $type.")
           ***                   33
     2481                                                         
unless $type eq 'HASH' or
     2482                                                           
(ref($first) and UNIVERSAL::isa($first, 'HASH'));

=item Branches

     line  err      %   true  false   branch
     ----- --- ------ ------ ------   ------
     2479         100     48     77   if (not scalar @_) { }
     2480  ***     50      0     48   unless $type eq 'HASH' or ref  
$first and UNIVERSAL::isa($first, 'HASH')

=item Conditions

     and 3 conditions

     line  err      %     !l  l&&!r   l&&r   expr
     ----- --- ------ ------ ------ ------   ----
     2480  ***      0      0      0      0   ref $first and  
UNIVERSAL::isa($first, 'HASH')

=back

We tackled this code at our second HTML::Template joint hacking
session.  More precisely, we tackled it on our third round of beer at
our second joint hacking session.  We simplified the code to the
following:

       if (!scalar(@_)) {
         croak("HTML::Template->param() : Single reference arg to  
param() must be a hash-ref!  You gave me a $type.")
             unless $type eq 'HASH' or UNIVERSAL::isa($first, 'HASH');
         push(@_, %$first);

All the code now became coverable by tests.  All tests passed.

=head1 Revisions of Tests

=head2 F<t/99-old-test-pl.t>

This file, the sole test file in version 2.7, has been left unchanged.

=head2 New F<t/*.t> Tests

=over 4

=item F<t/01-bad-args.t>

Test whether constructor fails with appropriate messages if passed bad
or missing arguments.

=item F<t/02-parse.t>

Test previously untested code inside C<HTML::Template::_parse()>.  Much
remains to be done, as we were just beginning our Phalanx efforts when
we were working in this area.

=item F<t/03-associate.t>

Test previously untested method C<HTML::Template::associateCGI()>.

=item F<t/04-type-source.t>

Test the 'type-source' style of constructor C<HTML::Template::new()>.

     $stemplate = HTML::Template->new(
         type   => 'scalarref',
         source => \$template_string,
     );

And similarly for cases where the source is an array or a filehandle.

=item F<t/05-blind-cache.t>

Test the previously untested C<blind_cache> option to constructor
C<HTML::Template::new()>.

     $template = HTML::Template->new(
         path => ['templates/'],
         filename => 'simple.tmpl',
         blind_cache => 1,
     );

I<Note:>  According to the documentation, when the C<blind_cache> option
is set to 1, ''the module behaves exactly as with normal
caching but does not check to see if the file has changed on each
request.''  Unfortunately, there is no documentation beyond this.
Specifically, (a) there is no test for it in F<t/99-old-test-pl.t>;
(b) there is no example of it in the documentation; and (c) we could
find no references to it in the archives of the HTML::Template mailing
list on Sourceforge.

So we were left to guess at how to code up a test.  We basically  
cloned the
test in F<t/99-old-test-pl.t> beginning at line 370.  We hypothesized  
that
if we
created an object with the C<blind_cache> option, slept for 1 second,  
then
changed the template file and got the same output string notwithstanding
the change in the template file, we could deem the test a pass.  And it
did indeed pass.  But since our understanding of the C<blind_cache>
option is limited, we don't yet know if the test was valid.

=item F<t/06-file-cache-dir.t>

Test edge cases in use of C<file_cache> and C<file_cache_dir> options
to constructor C<HTML::Template::new()>.  Example:  test case where
C<file_cache> option is set to C<undef> but a C<file_cache_dir> value is
provided; examine error message.

=item F<t/07-double-file-cache.t>

Test the previous untested C<double_file_cache> option to
C<HTML::Template::new()>.

     $template = HTML::Template->new(
         path => ['templates/'],
         filename => 'simple.tmpl',
         double_file_cache => 1,
         file_cache_dir => './blib/temp_cache_dir',
     );

=item F<t/08-cache-debug.t>

Automate testing of information printed to STDERR when the  
C<cache_debug>
option to
C<HTML::Template::new()> is turned on.  Tests for this functionality in
F<t/99-old-test-pl.t> were ''non automated,'' I<i.e.>, in order to  
assess
their results, the user would have had to turn the option on and  
visually
inspect STDERR as the test were displayed on the terminal.  Now the
output is captured and analyzed automatically.

=item F<t/09-caching-precluded.t>

Test that C<HTML::Template::new()> now precludes the
possibility of any of the six cache options having a
true value if the template source is a filehandle, string or array.  The
constructor now does additional error-checking and, if a violation is
found, the program dies and an appropriate error message is emitted via
C<croak> and analyzed.

=item F<t/10-param.t>

Test edge cases in use of C<HTML::Template::param()>.  More tests will
probably be added as we understand this function better.

=item F<t/11-non-file-templates.t>

Test whether simple output is correctly created when the template source
is a string, array or a filehandle.

=back

=head2 Supportive Testing Modules in F<t/testlib>

We are using core module F<Test::More> throughout.  In order to  
extend the
test coverage as far as possible, however, we have in certain
circumstances found it expedient to use functionality provided by other,
non-core CPAN modules.  Where appropriate, we have included this
functionality underneath the F<t/testlib> directory.

For example, to test HTML::Template's C<cache_debug> option, a user
currently has to uncomment that option and observe STDERR as the tests
are run.  We supplement by providing tests in F<t/08-cache-debug.t>
which automatically capture debugging messages printed to STDERR and
comparing those messages to predicted values with F<Test::More>  
functions.
We capture those debugging messages with parts of non-core CPAN
distribution F<IO::Capture>, included under F<t/testlib>.

=head2 The 700 Club

Recognizing your feelings about HTML::Template, we are trying to make
specific efforts to allay your fears that our Phalanx work will at some
point cause HTML::Template to 'break'.  One way that revisions to the
module I<could> make it break would be changes to the constructor (or to
functions called from within the constructor) which produced a different
data structure within the HTML::Template object.

We therefore have gone to some lengths to demonstrate that the object
created by C<new()> in 2.701 is the same as that created by C<new()> in
2.7.  We extracted a large portion of the tests found in
F<t/99-old-test-pl.t> which included a new constructor call and placed
them in six files with visibly distinct names: F<t/700-cons.t>,
F<t/701-cons.t>, ... F<t/706-cons.t>:  the 700 Club.  In these test  
files
we create an HTML::Template object with specified parameters with
version 2.701 and then make exactly the same call with version 2.7.  We
then compare the two objects with C<Test::More::is_deeply()>.  We do
this by including F<HTML/Template.pm> under F<t/testlib>.

The results were unambiguous:  the object created
by C<HTML::Template::new()> under 2.701 is the same as that created by
the constructor under 2.7.

=head1 Revisions of Documentation

Changes proposed for the documentation in F<Template.pm> are most easily
seen by examining the file F<diffpod> attached.
When you look at F<diffpod> you should see that most changes proposed
are cosmetic.  For a more consistent look in the HTML representation of
the docs, many variable names which previously appeared in the body  
font or
inside quotation marks have now been placed in monospace font.
Examples:

     121c121
     < If you called param() with a value like sam"my you'll get in  
trouble
     ---
     > If you called C<param()> with a value like sam"my you'll get  
in trouble

     406c406
     < to access the template text.  You can use "filename =>  
'file.tmpl'" to
     ---
     > to access the template text.  You can use C<filename =>  
'file.tmpl'> to

A few spelling errors were found and corrected.  Example:

     2838c2841
     < Just like C<param()>, C<query()> with no arguements returns  
all the
     ---
     > Just like C<param()>, C<query()> with no arguments returns all  
the

In other cases the only change is elimination of trailing whitespace at
the end of lines.  Other than these changes no changes have been
suggested so far for the documentation.  However, since we still have
more work to do on the code and tests, there may arise situations
where we will suggest changes in the documentation as well.

=head1 Recommendations

We recommend that the tarball accompanying this message -- less the six
tests in the ''700 Club'' -- be uploaded to CPAN as the next version of
HTML::Template.  In other words, we recommend that what we have called
version 2.701 to renamed (in F<Template.pm>) version 2.71.

There I<are> parts of HTML::Template for which we either (a) cannot yet
write tests (because we haven't tried it on OSes which support features
such as C<shared_cache>, C<double_cache> or C<memory_debug>) or have not
yet written tests (parts of C<param()> and C<_parse>).  Nonetheless, the
substantial increases in statement, branch, condition and subroutine
coverage we have achieved make HTML::Template stronger by providing
greater assurance that future revisions will not cause it to ''break.''
In particular, we recommend that any patches you are currently
considering for HTML::Template (such as those suggested on the
HTML::Template mailing list) be applied against 2.71 rather than 2.70.

Since we didn't change the functionality or interface of HTML::Template
in any respect, no current users of HTML::Template would be required to
upgrade to 2.71, nor would they get any surprises if they did so.  But
people installing HTML::Template for the first time would install a more
thoroughly tested version of it.

Thank you very much.

=cut




-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Html-template-users mailing list
Html-template-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/html-template-users

Reply via email to