allow C<substr 'hello', -10>
David Dyck [Mon, 10 Mar 1997 23:55:44 +0000 (15:55 -0800)]
Subject: patch substr to fetch rightmost n characters

This is not a 'porting' issue, but I've
cc'd the list since many of the experts are there.

to extract the the first 3 (or less characters in a
string one can say

$ perl -le '$x="abcdefg"; print substr($x , 0, 3)'
abc
$ perl -le '$x="ab"; print substr($x , 0, 3)'
ab

but to print the last 3 characters (or less)
the analogy doesn't work.

$ perl -le '$x="abcdefg"; print substr($x , -3)'
efg
$ perl -le '$x="ab"; print substr($x , -3)'

I was trying to let a string grow, but keep
it shorter than some maximum length.

Of course a work around is to check the length of
the string, eg

$ perl -le '$x="ab"; print length($x)<3?$x:substr($x , 0, 3)'
ab

but this doesn't seem reasonable.

Can anyone think of a reason against changing substr
to allow this feature.  I had expected it to work this way.
(as it does with the following patch)

$ ./perl -wle '$x="ab"; print substr($x , -3)'
ab

p5p-msgid: 97Mar10.155517pst.35716-2@gateway.fluke.com

pp.c

diff --git a/pp.c b/pp.c
index 863478d..fe3c675 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -1521,8 +1521,10 @@ PP(pp_substr)
     pos = POPi - arybase;
     sv = POPs;
     tmps = SvPV(sv, curlen);
-    if (pos < 0)
+    if (pos < 0) {
        pos += curlen + arybase;
+       if (pos < 0 && MAXARG < 3) pos = 0;
+    }
     if (pos < 0 || pos > curlen) {
        if (dowarn || lvalue)
            warn("substr outside of string");