Hi Andy / Everyone,
While we're looking at a new release, perhaps now is a proper time to get some
vmethods in that seem to be missing for everyone. I have added both substr for
scalars and delete for hash ops, as I'm sure many others have done. (Actually I
just looked at CVS and it looks like you already added delete.)
my substr vmethod:
-----------------------------------------------
$Template::Stash::SCALAR_OPS->{ substr } =
sub {
my ($scalar, $offset, $length) = @_;
return substr($scalar, $offset, $length);
};
-----------------------------------------------
In addition, I just had another thought of something that seems to be missing and a cause of problems on the mailing list occasionally. That would be missing back references in replace regular expressions. So here is a possible new vmethod called 'replace_backref' that would allow backref replacement without the security problems associated with backrefs. It's obviously not perfect, but I think if we just documented the feature correctly, then people would know what to expect. I also added a parameter to check globally or not, which also might be a good feature to add to the current replace.
------------------------------------------------------------
$Template::Stash::SCALAR_OPS->{'replace_backref'} = sub {
my ($str, $search, $replace, $do_global_match) = @_;
if (!defined($do_global_match)){
$do_global_match = 1; #match globally by default.
}
$replace = '' unless defined $replace;
return $str unless defined $str and defined $search;
if ($do_global_match){
$str =~ s!$search!
my @vals = ($1, $2, $3, $4, $5, $6, $7, $8, $9);
my $template = $replace;
$template =~ s/#(\d+)#/$vals[$1 - 1] || ''/eg;
$template;
!ge;
}else{
$str =~ s!$search!
my @vals = ($1, $2, $3, $4, $5, $6, $7, $8, $9);
my $template = $replace;
$template =~ s/#(\d+)#/$vals[$1 - 1] || ''/eg;
$template;
!e;
}
return $str;
};
------------------------------------------------------------
Here is an example of how it would be used:
------------------------------------------------------------
[% string = "Josh is an ok guy" %]
New String: [% string.replace_backref('^(\w+ is)', '#1# not') %]
Should Output: Josh is not an ok guy
[% string2 = 'Josh is not an ok guy' %]
New String: [% string2.replace_backref('(not) (an)', '#1# #2#') %]
Should output original string2.
------------------------------------------------------------
I used \d+ in the regexp up there, thinking that we may later on add more than
the 9 backrefs, but for now we could just use [1-9].
Some things that would need to be documented are:
Downfalls:
*) If you want to use #\d+# literally in your replace string your sol. However,
the user could simply use the normal replace instead.
*) Takes longer than the normal replace cause of the extra templating involved.
*) Currently only goes from 1-9 backrefs.
Options:
*) You can specify to not globally replace now.
I can pretty much guarantee people won't care about the extra replace time as
long as they are able to use their back references. (Those that are concerned
can simply override the vmethod.)
Any thoughts/changes on this idea/patch are welcome. (ie: different names for
it, or maybe a different format than #\d+#.)
-- Josh
_______________________________________________
templates mailing list
[email protected]
http://lists.template-toolkit.org/mailman/listinfo/templates