split()'s unused captures should be undef, not ''
Jeff Pinyan [Fri, 27 Jul 2001 14:00:37 +0000 (10:00 -0400)]
Message-ID: <Pine.GSO.4.21.0107271358310.28213-100000@crusoe.crusoe.net>

p4raw-id: //depot/perl@11475

pod/perlfunc.pod
pp.c
t/op/split.t

index 3f86c6a..4a76999 100644 (file)
@@ -4481,6 +4481,10 @@ characters at each point it matches that way.  For example:
 
 produces the output 'h:i:t:h:e:r:e'.
 
+Using the empty pattern C<//> specifically matches the null string, and is
+not be confused with the use of C<//> to mean "the last successful pattern
+match".
+
 Empty leading (or trailing) fields are produced when there positive width
 matches at the beginning (or end) of the string; a zero-width match at the
 beginning (or end) of the string does not produce an empty field.  For
@@ -4540,6 +4544,11 @@ Example:
        #...
     }
 
+As with regular pattern matching, any capturing parentheses that are not
+matched in a C<split()> will be set to C<undef> when returned:
+
+    @fields = split /(A)|B/, "1A2B3";
+    # @fields is (1, 'A', 2, undef, 3)
 
 =item sprintf FORMAT, LIST
 
diff --git a/pp.c b/pp.c
index 51e10de..658a890 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -4228,12 +4228,16 @@ PP(pp_split)
                for (i = 1; i <= rx->nparens; i++) {
                    s = rx->startp[i] + orig;
                    m = rx->endp[i] + orig;
-                   if (m && s) {
+
+                   /* japhy (07/27/01) -- the (m && s) test doesn't catch
+                      parens that didn't match -- they should be set to
+                      undef, not the empty string */
+                   if (m >= orig && s >= orig) {
                        dstr = NEWSV(33, m-s);
                        sv_setpvn(dstr, s, m-s);
                    }
                    else
-                       dstr = NEWSV(33, 0);
+                       dstr = &PL_sv_undef;  /* undef, not "" */
                    if (make_mortal)
                        sv_2mortal(dstr);
                    if (do_utf8)
index 170dfe8..f9c3bb9 100755 (executable)
@@ -5,7 +5,7 @@ BEGIN {
     @INC = '../lib';
 }
 
-print "1..45\n";
+print "1..46\n";
 
 $FS = ':';
 
@@ -254,3 +254,14 @@ print "ok 32\n";
     print "not " unless $r eq "he:o cruel world";
     print "ok 45\n";
 }
+
+
+{
+    # split /(A)|B/, "1B2" should return (1, undef, 2)
+    my @x = split /(A)|B/, "1B2";
+    print "not " unless
+      $x[0] eq '1' and
+      (not defined $x[1]) and
+      $x[2] eq '2';
+    print "ok 46\n";
+}