Re: custom vmethods

Tom Molesworth <tom-UE50auxAeIt4LjgWlUEQQwC/[email protected]> Wed, 24 Feb 2016 14:17:10 +0000
Newsgroups gmane.comp.lang.perl.modules.template-toolkit
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------090808060204060600000606
Content-Type: text/plain; charset=windows-1252; format=flowed
Content-Transfer-Encoding: 7bit

Hi Dave,

On 24/02/16 14:07, Dave Howorth wrote:
> On 2016-02-24 13:01, Tom Molesworth wrote:
>> On 24/02/16 12:44, Dave Howorth wrote:
>>> I'm trying to define a custom vmethod but not succeeding.
>>>
>>> I tried using the way described in the manual and also by calling
>>> define_vmethod. Both ways appear to have set up methods in the
>>> Template::Stash::SCALAR_OPS hashref but neither of them appears to
>>> work, even with a very simple body. Any clues to what I'm doing wrong
>>> gratefully received!
>>>
>>> In the perl:
>>>
>>> use Template::Stash;
>>> $Template::Stash::SCALAR_OPS->{uniprot_is_obsolete} =
>>>     sub {
>>>         return 42;
>>>     };
>>>
>>> sub forty_two { return 42; }
>>> Template::Stash->define_vmethod('scalar', 'forty_two', &forty_two);
>>>
>>> warn join ' ', keys %$Template::Stash::SCALAR_OPS, "\n";
>>
>> Those look fine - are you sure that [% representative %] is defined as a
>> scalar rather than a hashref/arrayref/object?
>
> representative is an object. An object is a scalar. If I replace the 
> definition of x in your test by x => sub {123} the test still passes.
>
> More to the point, representative.defined returns 1 and has the same 
> code (apart from the value of the numerical constant) as forty_two, 
> which doesn't return 42!

So it's a blessed hashref? If so, I'd expect that to be attempting to 
look up the key rather than calling scalar ops. Put those custom 
definitions in the 'hash' rather than 'scalar' ops definition and things 
should start working, although that's going to affect any hash lookups 
that use obj.key rather than obj.item(key).

See updated test attached.

cheers,

Tom


--------------090808060204060600000606
Content-Type: application/x-perl;
 name="tt2-vmethods.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="tt2-vmethods.pl"

#!/usr/bin/env perl 
use strict;
use warnings;
use Test::More;

use Template;
use Template::Stash;

my $obj = do {
	package whatever;
	# If you have a method, that should win
	# sub custom { }
	# If you have a blessed subref or other type of ref that'd normally call scalar ops, that should work
	# bless sub { }, __PACKAGE__;
	# but a plain or blessed hashref/arrayref isn't going to call scalar ops
	+{ }
};

my $tt = Template->new;
$Template::Stash::SCALAR_OPS->{ custom } = sub { 42 };
{
	$tt->process(\q{[% x.custom %]}, { x => $obj }, \my $out) or die $tt->error;
	is($out, '42', 'had 42 from SCALAR_OPS method');
}

Template::Stash->define_vmethod('hash', 'forty_three', sub { 43 });
{
	$tt->process(\q{[% x.forty_three %]}, { x => $obj }, \my $out) or die $tt->error;
	is($out, '43', 'had 43 from define_vmethod');
}
done_testing;


--------------090808060204060600000606
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
templates mailing list
[email protected]
http://mail.template-toolkit.org/mailman/listinfo/templates

--------------090808060204060600000606--