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


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

Reply via email to