Add tests and clarify pod for (?[ ])
authorKarl Williamson <public@khwilliamson.com>
Mon, 4 Feb 2013 21:03:09 +0000 (14:03 -0700)
committerKarl Williamson <public@khwilliamson.com>
Mon, 4 Feb 2013 21:17:52 +0000 (14:17 -0700)
A compliled '(?[ ])' embedded in a larger one is unaffected by what
regex modifiers are in effect at the time of the compilation of the
outer one; it retains, going forward, the modifiers it had when it was
first encountered.

pod/perlre.pod
t/re/regex_sets.t

index ae20e4d..d6a405f 100644 (file)
@@ -1913,12 +1913,20 @@ parenthesizing the component pieces:
 
  my $thai_or_lao = '( \p{Thai} + \p{Lao} )';
 
-Or you can make the components into instances of this construct by
-compiling them:
+But any modifiers will still apply to all the components:
+
+ my $lower = '\p{Lower} + \p{Digit}';
+ qr/(?[ \p{Greek} & $lower ])/i;
+
+matches upper case things.  You can avoid surprises by making the
+components into instances of this construct by compiling them:
 
  my $thai_or_lao = qr/(?[ \p{Thai} + \p{Lao} ])/;
+ my $lower = qr/(?[ \p{Lower} + \p{Digit} ])/;
 
-which causes the parenthesization to be done automatically for you.
+When these are embedded in another pattern, what they match does not
+change, regardless of parenthesization or what modifiers are in effect
+in that outer pattern.
 
 Due to the way that Perl parses things, your parentheses and brackets
 may need to be balanced, even including comments.  If you run into any
index eaa5c55..b70e7ec 100644 (file)
@@ -65,6 +65,25 @@ unlike(chr(ord("\N{LAO DIGIT ZERO}") - 1), $thai_or_lao_digit, 'embedded qr/(?[
 like("\N{LAO DIGIT NINE}", $thai_or_lao_digit, 'embedded qr/(?[ ])/ works');
 unlike(chr(ord("\N{LAO DIGIT NINE}") + 1), $thai_or_lao_digit, 'embedded qr/(?[ ])/ works');
 
+my $ascii_word = qr/(?[ \w ])/a;
+my $ascii_digits_plus_all_of_arabic = qr/(?[ \p{Digit} & $ascii_word + \p{Arabic} ])/;
+like("9", $ascii_digits_plus_all_of_arabic, "/a, then interpolating and intersection works for ASCII in the set");
+unlike("A", $ascii_digits_plus_all_of_arabic, "/a, then interpolating and intersection works for ASCII not in the set");
+unlike("\N{BENGALI DIGIT ZERO}", $ascii_digits_plus_all_of_arabic, "/a, then interpolating and intersection works for non-ASCII not in either set");
+unlike("\N{BENGALI LETTER A}", $ascii_digits_plus_all_of_arabic, "/a, then interpolating and intersection works for non-ASCII in one set");
+like("\N{ARABIC LETTER HAMZA}", $ascii_digits_plus_all_of_arabic, "interpolation and intersection is left-associative");
+like("\N{EXTENDED ARABIC-INDIC DIGIT ZERO}", $ascii_digits_plus_all_of_arabic, "interpolation and intersection is left-associative");
+
+my $kelvin = qr/(?[ \N{KELVIN SIGN} ])/;
+my $fold = qr/(?[ $kelvin ])/i;
+like("\N{KELVIN SIGN}", $kelvin, '"\N{KELVIN SIGN}" matches compiled qr/(?[ \N{KELVIN SIGN} ])/');
+unlike("K", $fold, "/i on outer (?[ ]) doesn't leak to interpolated one");
+unlike("k", $fold, "/i on outer (?[ ]) doesn't leak to interpolated one");
+
+my $kelvin_fold = qr/(?[ \N{KELVIN SIGN} ])/i;
+my $still_fold = qr/(?[ $kelvin_fold ])/;
+like("K", $still_fold, "/i on interpolated (?[ ]) is retained in outer without /i");
+like("k", $still_fold, "/i on interpolated (?[ ]) is retained in outer without /i");
 
 done_testing();