Hi Brad,
> I think I've found a small bug in param(). It's not a killer for me, but
> I thought I'd mention it. Here's an example that triggers the behavior
> I'm seeing (I'm using HTML::Template version 2.8, but I think 2.9 would
> behave this way, too):
>
> perl -MHTML::Template -wle'$o="<TMPL_VAR
> x>";$t=HTML::Template->new(scalarref=>\$o);$t->param(x=>\{});print
> $t->output()'
> Can't call method "isa" on unblessed reference at
> /opt/perl/lib/site_perl/5.8.8/HTML/Template.pm line 2527.
>
> Line 2527 looks like this:
>
> if (defined($value_type) and length($value_type) and ($value_type eq
> 'ARRAY' or ((ref($value) !~ /^(CODE)|(HASH)|(SCALAR)$/) and
> $value->isa('ARRAY')))) {
>
> What's happening is that $value_type is "REF", so it's getting past all
> the other checks and calling isa(), giving the error.
It should really be: UNIVERSAL::isa($value,'ARRAY')
rather than: $value->isa('ARRAY')
>
> First off, I think /^(CODE)|(HASH)|(SCALAR)$/) should instead be
> /^(CODE|HASH|SCALAR)$/). But if I'm following the logic correctly,
> I think it should be /^(CODE|GLOB|HASH|LVALUE|REF|SCALAR)$/).
>
> So I think the fix is to change that line to the following:
>
> if (defined($value_type) and length($value_type) and ($value_type eq
> 'ARRAY' or (($value_type !~ /^(CODE|GLOB|HASH|LVALUE|REF|SCALAR)$/)
> and $value->isa('ARRAY')))) {
>
> (Note that I also replaced ref($value) with $value_type.)
>
> When I rerun the above one-liner with this change, the output is
>
> REF(0x14b1d8)
>
> which is consistent with what you currently get if you pass, say, a
> hash reference, e.g.,
>
> perl -MHTML::Template -wle'$o="<TMPL_VAR
> x>";$t=HTML::Template->new(scalarref=>\$o);$t->param(x=>{});print
> $t->output()'
> HASH(0x124170)
>
> I hope that all makes sense. I have *not* run this through the
> tests, though, so I don't know if that will show up flaws in my
> understanding.
That all depends on your point of view.... :-)
H::T doesn't use hash's as values to params, so one would expect an
error (although it doesn't, it simply prints the hex code of the address
of the hash). I would argue that this behaviour "isn't good template
engine behaviour" -> H::T should probably croak since that param type
isn't supported.
However, some people have extended H::T to support "structure-esque"
template variables, eg: name.fist, name.last. If your version of
H::T supports this, then one could argue that passing in a hash (or hash
ref), should auto-vivify the template variables. For example:
$ht->param( name => { first => "fred", last => "flinstone"} );
auto-vivifies: "name", "name.first", "name.last"
One could also justify wanting the ability to pass in a sub-ref, thus
expecting that <TMPL_VAR sub { ... }> would execute the sub-ref.
cheers,
Mathew Robertson
|