pod/perluniintro: Update for EBCDIC and newer Unicode handling
authorKarl Williamson <khw@cpan.org>
Tue, 31 Mar 2015 03:28:33 +0000 (21:28 -0600)
committerKarl Williamson <khw@cpan.org>
Tue, 31 Mar 2015 03:51:37 +0000 (21:51 -0600)
This commit revises this document to account for the new 5.22 EBCDIC
handling.  It updates the advice for how to make sure your strings and
regular expression patterns are interpreted as Unicode to prefer \N{}
and charnames().  These automatically are portable to EBCDIC as well as
guaranteeing that the Unicode bug will not bite you.

pod/perluniintro.pod

index 26116a4..7a87874 100644 (file)
@@ -230,69 +230,98 @@ C<useperlio=define>.
 
 =head2 Unicode and EBCDIC
 
-Perl 5.8.0 also supports Unicode on EBCDIC platforms.  There,
-Unicode support is somewhat more complex to implement since
-additional conversions are needed at every step.
-
-Later Perl releases have added code that will not work on EBCDIC platforms, and
-no one has complained, so the divergence has continued.  If you want to run
-Perl on an EBCDIC platform, send email to perlbug@perl.org
+Perl 5.8.0 added support for Unicode on EBCDIC platforms.  This support
+was allowed to lapse in later releases, but was revived in 5.22.
+Unicode support is somewhat more complex to implement since additional
+conversions are needed.  See L<perlebcdic> for more information.
 
 On EBCDIC platforms, the internal Unicode encoding form is UTF-EBCDIC
 instead of UTF-8.  The difference is that as UTF-8 is "ASCII-safe" in
 that ASCII characters encode to UTF-8 as-is, while UTF-EBCDIC is
-"EBCDIC-safe".
+"EBCDIC-safe", in that all the basic characters (which includes all
+those that have ASCII equivalents (like C<"A">, C<"0">, C<"%">, I<etc.>)
+are the same in both EBCDIC and UTF-EBCDIC.  Often, documentation
+will use the term "UTF-8" to mean UTF-EBCDIC as well.  This is the case
+in this document.
 
 =head2 Creating Unicode
 
-To create Unicode characters in literals for code points above C<0xFF>,
-use the C<\x{...}> notation in double-quoted strings:
+This section applies fully to Perls starting with v5.22.  Various
+caveats for earlier releases are in the L</Earlier releases caveats>
+subsection below.
 
-    my $smiley = "\x{263a}";
+To create Unicode characters in literals,
+use the C<\N{...}> notation in double-quoted strings:
 
-Similarly, it can be used in regular expression literals
+ my $smiley_from_name = "\N{WHITE SMILING FACE}";
+ my $smiley_from_code_point = "\N{U+263a}";
 
-    $smiley =~ /\x{263a}/;
+Similarly, they can be used in regular expression literals
 
-At run-time you can use C<chr()>:
+ $smiley =~ /\N{WHITE SMILING FACE}/;
+ $smiley =~ /\N{U+263a}/;
 
-    my $hebrew_alef = chr(0x05d0);
+At run-time you can use:
 
-See L</"Further Resources"> for how to find all these numeric codes.
+ use charnames ();
+ my $hebrew_alef_from_name
+                      = charnames::string_vianame("HEBREW LETTER ALEF");
+ my $hebrew_alef_from_code_point = charnames::string_vianame("U+05D0");
 
 Naturally, C<ord()> will do the reverse: it turns a character into
 a code point.
 
-Note that C<\x..> (no C<{}> and only two hexadecimal digits), C<\x{...}>,
-and C<chr(...)> for arguments less than C<0x100> (decimal 256)
-generate an eight-bit character for backward compatibility with older
-Perls.  For arguments of C<0x100> or more, Unicode characters are
-always produced. If you want to force the production of Unicode
-characters regardless of the numeric value, use C<pack("U", ...)>
-instead of C<\x..>, C<\x{...}>, or C<chr()>.
+There are other runtime options as well.  You can use C<pack()>:
+
+ my $hebrew_alef_from_code_point = pack("U", 0x05d0);
+
+Or you can use C<chr()>, though it is less convenient in the general
+case:
+
+ $hebrew_alef_from_code_point = chr(utf8::unicode_to_native(0x05d0));
+ utf8::upgrade($hebrew_alef_from_code_point);
+
+The C<utf8::unicode_to_native()> and C<utf8::upgrade()> aren't needed if
+the argument is above 0xFF, so the above could have been written as
+
+ $hebrew_alef_from_code_point = chr(0x05d0);
 
-You can invoke characters
-by name in double-quoted strings:
+since 0x5d0 is above 255.
 
-    my $arabic_alef = "\N{ARABIC LETTER ALEF}";
+C<\x{}> and C<\o{}> can also be used to specify code points at compile
+time in double-quotish strings, but, for backward compatibility with
+older Perls, the same rules apply as with C<chr()> for code points less
+than 256.
 
-And, as mentioned above, you can also C<pack()> numbers into Unicode
-characters:
+C<utf8::unicode_to_native()> is used so that the Perl code is portable
+to EBCDIC platforms.  You can omit it if you're I<really> sure no one
+will ever want to use your code on a non-ASCII platform.  Starting in
+Perl v5.22, calls to it on ASCII platforms are optimized out, so there's
+no performance penalty at all in adding it.  Or you can simply use the
+other constructs that don't require it.
 
-   my $georgian_an  = pack("U", 0x10a0);
+See L</"Further Resources"> for how to find all these names and numeric
+codes.
 
-Note that both C<\x{...}> and C<\N{...}> are compile-time string
-constants: you cannot use variables in them.  if you want similar
-run-time functionality, use C<chr()> and C<charnames::string_vianame()>.
+=head3 Earlier releases caveats
 
-If you want to force the result to Unicode characters, use the special
-C<"U0"> prefix.  It consumes no arguments but causes the following bytes
-to be interpreted as the UTF-8 encoding of Unicode characters:
+On EBCDIC platforms, prior to v5.22, using C<\N{U+...}> doesn't work
+properly.
 
-   my $chars = pack("U0W*", 0x80, 0x42);
+Prior to v5.16, using C<\N{...}> with a character name (as opposed to a
+C<U+...> code point) required a S<C<use charnames :full>>.
 
-Likewise, you can stop such UTF-8 interpretation by using the special
-C<"C0"> prefix.
+Prior to v5.14, there were some bugs in C<\N{...}> with a character name
+(as opposed to a C<U+...> code point).
+
+C<charnames::string_vianame()> was introduced in v5.14.  Prior to that,
+C<charnames::vianame()> should work, but only if the argument is of the
+form C<"U+...">.  Your best bet there for runtime Unicode by character
+name is probably:
+
+ use charnames ();
+ my $hebrew_alef_from_name
+                  = pack("U", charnames::vianame("HEBREW LETTER ALEF"));
 
 =head2 Handling Unicode
 
@@ -492,6 +521,9 @@ returns the string
 
 which is ready to be printed.
 
+(C<\\x{}> is used here instead of C<\\N{}>, since it's most likely that
+you want to see what the native values are.)
+
 =head2 Special Cases
 
 =over 4
@@ -605,8 +637,14 @@ All the properties that begin with C<\p> (and its inverse C<\P>) are actually
 character classes that are Unicode-aware.  There are dozens of them, see
 L<perluniprops>.
 
-You can use Unicode code points as the end points of character ranges, and the
-range will include all Unicode code points that lie between those end points.
+Starting in v5.22, you can use Unicode code points as the end points of
+character ranges, and the range will include all Unicode code points
+that lie between those end points, inclusive.
+
+ qr/ [\N{U+03]-\N{U+20}] /x
+
+includes the code points
+C<\N{U+03}>, C<\N{U+04}>, ..., C<\N{U+20}>.
 
 =item *