1
2
3
4
5
6
7
8
9
$ cat encode_locale.pl
use utf8;
use Encode::Locale;
binmode STDOUT, ':encoding(console_out)';
print "Cäsar\n";
$ perl encode_locale.pl
Cäsar
2023-11-12T16:42:26 rostiVollkommen richtig. Und welche Bytes das sind, definiert UNICODE. D.h., UNICODE vermittelt zwischen Codepoint und Bytesequenz. Dieser Algorithmus ist in Encode implementiert.
MFG
QuoteAlternately, if the handle is not
marked with an encoding but you attempt to write characters with
code points over 255, raises an exception.
2023-11-13T11:14:50 rostigenügend Menschen sind verleitet zu glauben, dass "Höhere" Interpreter-Sprachen alles regeln (no ’ne Art Do-what-I-mean). Denen sind Grundlagen doch eher unbekannt.Die Annahme daß Perl per se Zeichenorientiert funktioniert ist falsch.
2023-11-13T11:34:28 GwenDragon2023-11-13T11:14:50 rostigenügend Menschen sind verleitet zu glauben, dass "Höhere" Interpreter-Sprachen alles regeln (no ’ne Art Do-what-I-mean). Denen sind Grundlagen doch eher unbekannt.Die Annahme daß Perl per se Zeichenorientiert funktioniert ist falsch.
Und ohne Modulcode einzusehen oder Testcases zu schreiben, aus der Notwendigkeit kommt eine:r nicht immer raus.
2023-11-13T08:03:08 barneyIn meinem Beispielsprogramm habe ich explizit gesagt dass es sich um die Konsole-Programme von OTOBO handelt. In der Webapp wird es anders gemacht.
2023-11-12T18:16:39 rostiAuf diesen ganzen Hick-Hack kann man aber auch verzichten indem man die Kodierung gar nicht erst mit use utf8; einschaltet, denn ein print "€"; hat schon immer die richtigen Bytes ausgegeben vorausgesetzt man hat den Editior angewiesen die Scriptdatei in utf8 zu speichern.
Quotebinmode STDOUT, ':encoding(console_out)'; sorgt dafür daß die interne Kodierung für die Ausgabe auf STDOUT abgeschaltet wird. Aber nur dann wenn die interne Kodierung mit der von der Konsole benutzten Kodierung übereinstimmt.
QuoteWelche Zeichenkodierung jedoch in der Scriptdatei vorliegt ist allein durch die aus der Datei gelesenen Bytes gegeben. D.h., welche Kodierung beim Speichern der Datei angegeben wurde. Ein use utf8; hat auf Letzteres gar keinen Einfluß.
QuoteIch weiß nicht was "interne Kodierung abschalten" bedeuten soll. Bei ':encoding(console_out)' wird doch nur das Terminal gefragt welches Encoding das Terminal erwartet. Das ist dann so etwas wie 'ascii', 'latin1' oder 'utf8'. Wenn ein String auf STDOUT herausgeschrieben wird, dann wird dieser entsprechend kodiert.
QuoteDas Encoding der Konsole gilt nämlich nur für die Konsole und legt fest, wie die zu Zeichen gehörigen Bytesequenzen darzustellen sind.
QuoteWas ':encoding(console_out)' macht ist also kein Handshake, Deine Annahme das damit das Terminal befragt wird ist falsch.
QuoteFor programs running in a terminal window (called a "Console" on some systems) the "locale" encoding is usually a good choice for what to expect as input and output. Some systems allows us to query the encoding set for the terminal and Encode::Locale will do that if available and make these encodings known under the Encode aliases "console_in" and "console_out". For systems where we can't determine the terminal encoding these will be aliased as the same encoding as "locale". The advice is to use "console_in" for input known to come from the terminal and "console_out" for output to the terminal.
QuoteEin Terminal erwartet keine Encoding sondern Bytesequenzen.
QuoteEin Terminal erwartet keine Encoding sondern Bytesequenzen.
QuoteEin Unicode Codepoint der in einen bestimmten Encoding kodiert ist, ist doch eine Bytesequenz.
QuoteEin Unicode Codepoint der in einen bestimmten Encoding kodiert ist, ist doch eine Bytesequenz.
QuoteNein. Der Codepoint sagt überhaupt nichts über die Kodierung aus. Bspw. hat das 'ä' den Codepoint U+E4 und kann verschieden kodiert sein, also auch Latin1 oder ANSI. Somit ist der Codepoint nur ein numerischer Identifier für ein Zeichen.
QuoteEin Terminal erwartet keine Encoding sondern Bytesequenzen.
2023-11-14T09:30:48 rostiKonsole ist IO, print schreibt auf STDOUT per default. Und STDOUT kennt keine Kodierung sondern erwartet Bytes.
führt bestenfalls zu einer Fehlermeldung sofern die perlinterne Kodierung mit der Konsolekonfiguration nicht übereinstimmt. Auf die Kodierung selbst hat dieses Konstrukt keinen Einfluß.
1 2 3
binmode(STDOUT, ":utf8"); my $bytes = pack "C", 0xE4; # ISO-8859-1, Latin1 print $bytes;
1 2 3
binmode(STDOUT, ":utf8"); my $bytes = pack "CCC", 0xE2, 0x82, 0xAC; print $bytes;
1
2
3
4
5
6
binmode(STDOUT, ":utf8");
my $bytes = pack "CCC", 0xE2, 0x82, 0xAC;
utf8::decode($bytes);
if ($bytes =~ m/\p{Currency_Symbol}/ ) {
print "$bytes is a currency symbol\n";
}
1 2 3
binmode(STDOUT, ":utf8"); my $bytes = pack "CCC", 0xE2, 0x82, 0xAC; print $bytes;
2023-11-14T11:09:48 barneyJa, klar. Wenn ich explizite Bytes raus schreiben will dann darf ich den IO-Layer für 'utf-8' nicht einschalten.
Der Vollständigkeit halber noch ein Beispiel im dem ich eine Bytesequenz habe die einen Codepoint kodiert. Vor dem Rausschreiben will ich damit aber noch etwas mehr oder weniger Sinnvolles machen:
Code: (dl )1
2
3
4
5
6binmode(STDOUT, ":utf8");
my $bytes = pack "CCC", 0xE2, 0x82, 0xAC;
utf8::decode($bytes);
if ($bytes =~ m/\p{Currency_Symbol}/ ) {
print "$bytes is a currency symbol\n";
}