Make the point a bit clearer after suggestion from Merijin
[p5sagit/p5-mst-13.2.git] / pod / perlunicode.pod
index 26e704a..d2c48e2 100644 (file)
@@ -274,7 +274,7 @@ written right to left.
 =head2 Scripts
 
 The scripts available via C<\p{...}> and C<\P{...}>, for example
-C<\p{Latin}> or \p{Cyrillic>, are as follows:
+C<\p{Latin}> or C<\p{Cyrillic}>, are as follows:
 
     Arabic
     Armenian
@@ -363,12 +363,12 @@ and further derived properties:
     ID_Continue     ID_Start + Mn + Mc + Nd + Pc
 
     Any             Any character
-    Assigned        Any non-Cn character (i.e. synonym for C<\P{Cn}>)
-    Unassigned      Synonym for C<\p{Cn}>
+    Assigned        Any non-Cn character (i.e. synonym for \P{Cn})
+    Unassigned      Synonym for \p{Cn}
     Common          Any character (or unassigned code point)
                     not explicitly assigned to a script
 
-For backward compatability, all properties mentioned so far may have C<Is>
+For backward compatibility, all properties mentioned so far may have C<Is>
 prepended to their name (e.g. C<\P{IsLu}> is equal to C<\P{Lu}>).
 
 =head2 Blocks
@@ -393,7 +393,7 @@ For more about blocks, see:
 
 Blocks names are given with the C<In> prefix. For example, the
 Katakana block is referenced via C<\p{InKatakana}>. The C<In>
-prefix may be omitted if there is no nameing conflict with a script
+prefix may be omitted if there is no naming conflict with a script
 or any other property, but it is recommended that C<In> always be used
 to avoid confusion.
 
@@ -615,6 +615,91 @@ And finally, C<scalar reverse()> reverses by character rather than by byte.
 
 =back
 
+=head2 User-defined Character Properties
+
+You can define your own character properties by defining subroutines
+that have names beginning with "In" or "Is".  The subroutines must be
+visible in the package that uses the properties.  The user-defined
+properties can be used in the regular expression C<\p> and C<\P>
+constructs.
+
+The subroutines must return a specially formatted string: one or more
+newline-separated lines.  Each line must be one of the following:
+
+=over 4
+
+=item *
+
+Two hexadecimal numbers separated by horizontal whitespace (space or
+tabulator characters) denoting a range of Unicode codepoints to include.
+
+=item *
+
+Something to include, prefixed by "+": either an built-in character
+property (prefixed by "utf8::"), for all the characters in that
+property; or two hexadecimal codepoints for a range; or a single
+hexadecimal codepoint.
+
+=item *
+
+Something to exclude, prefixed by "-": either an existing character
+property (prefixed by "utf8::"), for all the characters in that
+property; or two hexadecimal codepoints for a range; or a single
+hexadecimal codepoint.
+
+=item *
+
+Something to negate, prefixed "!": either an existing character
+property (prefixed by "utf8::") for all the characters except the
+characters in the property; or two hexadecimal codepoints for a range;
+or a single hexadecimal codepoint.
+
+=back
+
+For example, to define a property that covers both the Japanese
+syllabaries (hiragana and katakana), you can define
+
+    sub InKana {
+       return <<END;
+    3040\t309F
+    30A0\t30FF
+    END
+    }
+
+Imagine that the here-doc end marker is at the beginning of the line.
+Now you can use C<\p{InKana}> and C<\P{InKana}>.
+
+You could also have used the existing block property names:
+
+    sub InKana {
+       return <<'END';
+    +utf8::InHiragana
+    +utf8::InKatakana
+    END
+    }
+
+Suppose you wanted to match only the allocated characters,
+not the raw block ranges: in other words, you want to remove
+the non-characters:
+
+    sub InKana {
+       return <<'END';
+    +utf8::InHiragana
+    +utf8::InKatakana
+    -utf8::IsCn
+    END
+    }
+
+The negation is useful for defining (surprise!) negated classes.
+
+    sub InNotKana {
+       return <<'END';
+    !utf8::InHiragana
+    -utf8::InKatakana
+    +utf8::IsCn
+    END
+    }
+
 =head2 Character encodings for input and output
 
 See L<Encode>.
@@ -645,7 +730,8 @@ Level 1 - Basic Unicode Support
         [ 3] . \p{...} \P{...}
         [ 4] now scripts (see UTR#24 Script Names) in addition to blocks
         [ 5] have negation
-        [ 6] can use look-ahead to emulate subtraction (*)
+        [ 6] can use regular expression look-ahead [a]
+             or user-defined character properties [b] to emulate subtraction
         [ 7] include Letters in word characters
         [ 8] note that perl does Full casefolding in matching, not Simple:
              for example U+1F88 is equivalent with U+1F000 U+03B9,
@@ -658,7 +744,7 @@ Level 1 - Basic Unicode Support
              (should also affect <>, $., and script line numbers)
              (the \x{85}, \x{2028} and \x{2029} do match \s)
 
-(*) You can mimic class subtraction using lookahead.
+[a] You can mimic class subtraction using lookahead.
 For example, what TR18 might write as
 
     [{Greek}-[{UNASSIGNED}]]
@@ -674,6 +760,8 @@ But in this particular example, you probably really want
 
 which will match assigned characters known to be part of the Greek script.
 
+[b] See L</User-defined Character Properties>.
+
 =item *
 
 Level 2 - Extended Unicode Support
@@ -828,8 +916,9 @@ needed.  The BOM signatures will be 0x00 0x00 0xFE 0xFF for BE and
 UCS-2, UCS-4
 
 Encodings defined by the ISO 10646 standard.  UCS-2 is a 16-bit
-encoding, UCS-4 is a 32-bit encoding.  Unlike UTF-16, UCS-2
-is not extensible beyond 0xFFFF, because it does not use surrogates.
+encoding.  Unlike UTF-16, UCS-2 is not extensible beyond 0xFFFF,
+because it does not use surrogates.  UCS-4 is a 32-bit encoding,
+functionally identical to UTF-32.
 
 =item *
 
@@ -840,7 +929,13 @@ transport/storage is not eight-bit safe.  Defined by RFC 2152.
 
 =back
 
-=head2 Security Implications of Malformed UTF-8
+=head2 Security Implications of Unicode
+
+=over 4
+
+=item *
+
+Malformed UTF-8
 
 Unfortunately, the specification of UTF-8 leaves some room for
 interpretation of how many bytes of encoded output one should generate
@@ -853,6 +948,37 @@ warnings;>) Perl will warn about non-shortest length UTF-8 (and other
 malformations, too, such as the surrogates, which are not real
 Unicode code points.)
 
+=item *
+
+Regular expressions behave slightly differently between byte data and
+character (Unicode data).  For example, the "word character" character
+class C<\w> will work differently when the data is all eight-bit bytes
+or when the data is Unicode.
+
+In the first case, the set of C<\w> characters is either small (the
+default set of alphabetic characters, digits, and the "_"), or, if you
+are using a locale (see L<perllocale>), the C<\w> might contain a few
+more letters according to your language and country.
+
+In the second case, the C<\w> set of characters is much, much larger,
+and most importantly, even in the set of the first 256 characters, it
+will most probably be different: as opposed to most locales (which are
+specific to a language and country pair) Unicode classifies all the
+characters that are letters as C<\w>.  For example: your locale might
+not think that LATIN SMALL LETTER ETH is a letter (unless you happen
+to speak Icelandic), but Unicode does.
+
+As discussed elsewhere, Perl tries to stand one leg (two legs, as
+camels are quadrupeds?) in two worlds: the old world of bytes and the new
+world of characters, upgrading from bytes to characters when necessary.
+If your legacy code is not explicitly using Unicode, no automatic
+switchover to characters should happen, and characters shouldn't get
+downgraded back to bytes, either.  It is possible to accidentally mix
+bytes and characters, however (see L<perluniintro>), in which case the
+C<\w> might start behaving differently.  Review your code.
+
+=back
+
 =head2 Unicode in Perl on EBCDIC
 
 The way Unicode is handled on EBCDIC platforms is still rather
@@ -990,12 +1116,79 @@ in the Perl source code distribution.
 
 =head1 BUGS
 
+=head2 Interaction with locales
+
 Use of locales with Unicode data may lead to odd results.  Currently
 there is some attempt to apply 8-bit locale info to characters in the
 range 0..255, but this is demonstrably incorrect for locales that use
 characters above that range when mapped into Unicode.  It will also
 tend to run slower.  Use of locales with Unicode is discouraged.
 
+=head2 Interaction with extensions
+
+When perl exchanges data with an extension, the extension should be
+able to understand the UTF-8 flag and act accordingly. If the
+extension doesn't know about the flag, the risk is high that it will
+return data that are incorrectly flagged.
+
+So if you're working with Unicode data, consult the documentation of
+every module you're using if there are any issues with Unicode data
+exchange. If the documentation does not talk about Unicode at all,
+suspect the worst and probably look at the source to learn how the
+module is implemented. Modules written completely in perl shouldn't
+cause problems. Modules that directly or indirectly access code written
+in other programming languages are at risk.
+
+For affected functions the simple strategy to avoid data corruption is
+to always make the encoding of the exchanged data explicit. Choose an
+encoding you know the extension can handle. Convert arguments passed
+to the extensions to that encoding and convert results back from that
+encoding. Write wrapper functions that do the conversions for you, so
+you can later change the functions when the extension catches up.
+
+To provide an example let's say the popular Foo::Bar::escape_html
+function doesn't deal with Unicode data yet. The wrapper function
+would convert the argument to raw UTF-8 and convert the result back to
+perl's internal representation like so:
+
+    sub my_escape_html ($) {
+      my($what) = shift;
+      return unless defined $what;
+      Encode::decode_utf8(Foo::Bar::escape_html(Encode::encode_utf8($what)));
+    }
+
+Sometimes, when the extension does not convert data but just stores
+and retrieves them, you will be in a position to use the otherwise
+dangerous Encode::_utf8_on() function. Let's say the popular
+C<Foo::Bar> extension, written in C, provides a C<param> method that
+lets you store and retrieve data according to these prototypes:
+
+    $self->param($name, $value);            # set a scalar
+    $value = $self->param($name);           # retrieve a scalar
+
+If it does not yet provide support for any encoding, one could write a
+derived class with such a C<param> method:
+
+    sub param {
+      my($self,$name,$value) = @_;
+      utf8::upgrade($name);     # make sure it is UTF-8 encoded
+      if (defined $value)
+        utf8::upgrade($value);  # make sure it is UTF-8 encoded
+        return $self->SUPER::param($name,$value);
+      } else {
+        my $ret = $self->SUPER::param($name);
+        Encode::_utf8_on($ret); # we know, it is UTF-8 encoded
+        return $ret;
+      }
+    }
+
+Some extensions provide filters on data entry/exit points, such as
+DB_File::filter_store_key and family. Look out for such filters in
+the documentation of your extensions, they can make the transition to
+Unicode data much easier.
+
+=head2 speed
+
 Some functions are slower when working on UTF-8 encoded strings than
 on byte encoded strings.  All functions that need to hop over
 characters such as length(), substr() or index() can work B<much>