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.
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.
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.
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. sos@rolfrost.de.