Thanks for the test script. I'll be sure to write one up next time.

To see the problem, the DateTime::Duration object needs to be more than 1 level deep, like so:


use strict; use warnings; use Template; use DateTime::Duration;

 my $template = Template->new();
 my $duration = DateTime::Duration->new( years => 3 );
 my %top =  ( duration => $duration );

 $template->process(\*DATA, { top => \%top })
     || die $template->error();

 __DATA__
 [% IF top.duration.years -%]
 *  The duration is: [% top.duration.years %] years
 [% ELSE -%]
 *  The duration is less than a year.
 [% END -%]

My fix has worked fine for me. DateTime's author, Dave Rolsky suggested an even better fix:

use Scalar::Util qw(refaddr);
my $atroot = ref $root && refaddr($root) == refaddr($self);

There is probably a good reason why the compare method is not overloaded. Dave is probably the best person to answer that.

I agree that adding any code to a subroutine that gets executed for every dot operation can be problematic. On the other hand, checking whether 2 references point to the same memory location is the most sure way to know whether 2 objects are the same.


Arshavir



Andy Wardley wrote:

Arshavir Grigorian wrote:


I am trying to access a DateTime::Duration method from within my TT template and getting an getting the following exception:



I don't see any problem. Here's my test script:

 use strict;
 use warnings;
 use Template;
 use DateTime::Duration;

 my $template = Template->new();
 my $duration = DateTime::Duration->new( years => 3 );

 $template->process(\*DATA, { duration => $duration })
     || die $template->error();

 __DATA__
 [% IF duration.years -%]
 *  The duration is: [% duration.years %] years
 [% ELSE -%]
 *  The duration is less than a year.
 [% END -%]

I get the correct output and no exception. Can you "fix" my example to demonstrate the problem?



If we replace it with the following, the logic will short circuit and we will never have to compare apples to oranges.

my $atroot = ((ref ($root) eq ref ($self)) && ($root eq $self));

It should not break anything else. Right?



Who knows? That's what the test suite is for. :-)

If you have something that looks like a bug, you need to write a short test like the above that clearly demonstrates the problem, add it to the test suite, apply the fix, and then run the test suite to prove that the fix fixes the bug and doesn't break anything else.

But I'm not in favour of adding a hack in TT to work around one particular
module's problems, especially when it's adding extra code that will be executed every time every node of every dotted variable is evaluated in every template in every TT installation across the World. That's an awful lot of dotops. :-)


It would be much easier to fix the real problem in DateTime::Duration
which overloads <=> and cmp to _compare_overload() but then dies when
it actually gets called:

 sub _compare_overload
 {
     die "DateTime::Duration does not overload comparison.  See the documentation on 
the compare() method for details.";
 }


A





_______________________________________________
templates mailing list
[EMAIL PROTECTED]
http://lists.template-toolkit.org/mailman/listinfo/templates

Reply via email to