[Templates] Vmethods to add to 2.15

Josh Rosenbaum josh@infogears.com
Wed, 01 Feb 2006 12:48:30 -0700


Andy Wardley wrote:
>> -----------------------------------------------
>>  sub {
>>    my ($scalar, $offset, $length) = @_;
>>    return substr($scalar, $offset, $length);
>>  };
>> -----------------------------------------------
> 
> Unfortunately it's not as simple as that.  Perl distinguishes between
> substr($scalar, $offset, undef) and substr($scalar, $offset) so we have
> to hard-code the alternatives (unless anyone knows another way?).  I've
> also added code the handle the 4th argument to provide a replacement string,
> thanks to http://rt.cpan.org/Ticket/Display.html?id=2619


============================================================
Hmm, what a pain. I'd be interested in knowing another way myself. Usually I'd just do something like ($length ? $length : ()) which works with normal subs, but not this.
============================================================


>     'substr' => sub {
>         my ($text, $offset, $length, $replacement) = @_;
>         $offset ||= 0;
> 
>         if(defined $length) {
>             if (defined $replacement) {
>                 my $removed = substr( $text, $offset, $length );
>                 substr( $text, $offset, $length ) = $replacement;
>                 return $removed;
>             }
>             else {
>                 return substr( $text, $offset, $length );
>             }
>         }
>         else {
>             return substr( $text, $offset );
>         }
>     },
> 
> I think that covers all bases.  Damn shame when something that should be
> so simple turns out so messy.  Ho hum, that's Perl sometimes.

============================================================
Hmm, it doesn't seem like the replacement would actually even doing anything, since it's operating on a copy of the text. Unless you pass by reference, I don't think you're going to be able to do this. If you do manage to get something worked out, then I'd suggest also adding replacement to the second else, for the case that you want to replace all ending text after a certain point with something else.
============================================================



>> 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. 
> 
> Yeah, this is a nuisance, but I haven't yet seen an implementation that 
> solves all the problems securely and robustly.  I'm not keen on adding a
> new syntax for back-references.  What was your reasoning for that over
> the regular $1 or \1 syntax?


============================================================
I just didn't want people thinking they were using Perl variables, and that things would parse the same. The $1 syntax would be fine, though.
============================================================


> This is the most promising candidate from Craig Barratt. 
> 
> sub replace { 
>     my ($str, $search, $replace) = @_;
>     $replace = '' unless defined $replace;
>     return $str unless defined $str and defined $search;
> 
>     $str =~ s{ $search } {
> 	my $r = $replace;
> 	my @d = (0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
> 	$r =~ s/\$(\d+)/$d[$1]/eg;
> 	$r;
>     }egx;
> 
>     return $str;
> }
> 
> It's limited to the first 9 captures only (no $10, $11, etc) and it 
> doesn't handle escaped '\$' in the replacement string.  But apart from
> that, it seems to do the job without opening up any security holes.

============================================================
That's basically exactly what I did, but I allowed global search and replace as well. I guess Craig should've patented this one-click scheme! ;) j/k

I'm going to check out the replace based on what Nik did. I had noticed him posting to this list before about that, and actually started looking into what he was doing along with some other ways to do it, but got lost in other stuff I needed to get done.

Also I am also wondering about what Paul Seamons said:
> Also - just wondering - how long has @- been supported - and does it incur any 
> penalties.  (Guess I could look this up myself).

I had done a quick search earlier today, but didn't see much related to what version @- started in. (Makes me think it was probably an earlier version.) I'll try to look into this further if no one else responds.

-- Josh