Fehlermeldung bei der Ausgabe von UTF-8: Wide Character in print

Wide character in print at ... line xy

Diese Fehlermeldung erscheint, wenn bei der Print-Ausgabe von UTF-8-kodierten Zeichen ab 3 Bytes die Kodierung nicht ausgeschaltet wurde. Beispiel:

# Erzeuge das €-Zeichen aus dem Codepoint
my $char = pack "U", 0x20AC;
# Versuche ein print mit eingeschalteter Kodierung
print $char; # Wide character in print at

Zum Verständnis: Mittels pack und der "U"-Schablone wird eine utf-8-kodierte Zeichenkette erzeugt, d.h., perlintern ist die Kodierung eingeschaltet. Und weil das so ist, erscheint bei der print-Ausgabe die obenstehende Fehlermeldung. Abhelfe:

use bytes; # vor der print-Ausgabe

Damit wird die perlinterne Kodierung ausgeschaltet und es gilt die Bytesemantic.

Umschalten zur Bytorientierung

Natürlich gib es mehrere Möglichkeiten. use bytes ist jedoch dann zweckmäßig wenn für einen ganzen Codeblock umgeschaltet werden soll. encode_utf8($str) hingegen schaltet die Kodierung nur für einen bestimmten String ab. Das ist der Unterschied und untenstehend sei die Performanze beider Verfahren miteinander verglichen:

use Benchmark qw(:all);
use Encode;

my $chr = pack "U", 0x20AC;

cmpthese(1000000, {
    'Encode' => sub{
        my $enc = encode_utf8($chr);
        my $bin = pack("N", length $enc).$enc;
    },
    'uBytes' => sub{
        use bytes;
        my $bin = pack("N", length $chr).$chr;
    },
});

            Rate Encode uBytes
Encode  346021/s     --   -79%
uBytes 1639344/s   374%     --

use bytes ist also deutlich performanter und damit immer dann angebracht wenn für sehr viele Zeichenketten die Bytesemantic sicherzustellen ist, beispielsweise beim Serialisieren komplexer Datenstrukturen.

Bytesequenzen kennen keine Kodierung

Perlintern werden Zeichenketten stets mit einer bestimmten Kodierung verwaltet. Andere Daten sind Bytesequenzen bei denen die Kodierung undefiniert ist. Sämtliche Daten die Perl von außerhalb bekommt, also von CGI/1.1, aus Dateien, von Datenbankhandle, sind keine Zeichenketten sondern Bytesequenzen ohne perlintern definierte Kodierung.

Das Pragma bytes und dessen Geltungsbereich

Betrachte untenstehende Funktion. Das Pragma bytes ist nur innerhalb dieser Funktion gültig. D.h., daß die Zeichenkodierung nur für die print-Ausgabe ausgeschaltet wird, danach ist sie wieder eingeschaltet.

sub say{
    use bytes;
    local $, = "\n";
    local $\ = "\n";
    print @_;
}

(In der Doku wird das Einschalten der Kodierung als Kapselung bezeichnet)


Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. s​os­@rolf­rost.de.