Senza use utf8
Perl interpreta la tua stringa come una sequenza di caratteri a byte singolo. Ci sono quattro byte nella tua stringa come puoi vedere da questo:
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
I primi tre byte compongono il tuo personaggio, l'ultimo è il line-feed.
La chiamata a print
invia questi quattro caratteri a STDOUT. La tua console quindi risolverà come visualizzare questi caratteri. Se la tua console è impostata per utilizzare UTF8, interpreterà quei tre byte come un singolo carattere e questo è ciò che viene visualizzato.
Se aggiungiamo nel utf8
modulo, le cose sono diverse. In questo caso, Perl interpreta la tua stringa come solo due caratteri.
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10
Per impostazione predefinita, il livello IO di Perl presume che funzioni con caratteri a byte singolo. Quindi, quando provi a stampare un carattere multibyte, Perl pensa che qualcosa non va e ti dà un avvertimento. Come sempre, puoi ottenere ulteriori spiegazioni per questo errore includendo use diagnostics
. Dirà questo:
(S utf8) Perl ha incontrato un carattere wide (> 255) quando non se ne aspettava uno. Questo avviso è attivo per impostazione predefinita per I / O (come la stampa). Il modo più semplice per silenziare questo avviso è semplicemente aggiungere il livello: utf8 all'output, ad esempio binmode STDOUT, ': utf8'. Un altro modo per disattivare l'avviso consiste nell'aggiungere nessun avviso "utf8"; ma questo è spesso più vicino a barare. In generale, dovresti contrassegnare esplicitamente il filehandle con una codifica, vedi open e perlfunc / binmode.
Come altri hanno sottolineato, devi dire a Perl di accettare output multibyte. Ci sono molti modi per farlo (vedere il Tutorial Perl Unicode per alcuni esempi). Uno dei modi più semplici è usare il -CS
flag della riga di comando, che dice ai tre filehandle standard (STDIN, STDOUT e STDERR) di gestire UTF8.
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
vs
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode è un'area grande e complessa. Come hai visto, molti programmi semplici sembrano fare la cosa giusta, ma per le ragioni sbagliate. Quando inizi a riparare una parte del programma, le cose spesso peggiorano finché non avrai risolto tutto il programma.