Perché i miei test Perl falliscono con `use encoding ‘utf8’`?

Sono confuso con questo script di test:

#!perl use strict; use warnings; use encoding 'utf8'; use Test::More 'no_plan'; ok('áá' =~ m/á/, 'ok direct match'); my $re = qr{á}; ok('áá' =~ m/$re/, 'ok qr-based match'); like('áá', $re, 'like qr-based match'); 

I tre test falliscono, ma mi aspettavo che l’ use encoding 'utf8' aggiornasse sia il letterale áá che il qr based alle espressioni utf8 e quindi áá i test.

Se rimuovo la riga di use encoding , i test passano come previsto, ma non riesco a capirlo perché dovrebbero fallire nella modalità utf8 .

Sto usando perl 5.8.8 su Mac OS X (versione di sistema).

Non usare il pragma di encoding . È rotto. (Juerd Waalboer ha tenuto una grande chiacchierata in cui ha parlato di questo a YAPC :: EU 2k8.)

Fa almeno due cose alla volta che non appartengono insieme:

  1. Specifica una codifica per il tuo file sorgente.
  2. Specifica una codifica per l’input / output del file.

E aggiungere ferite per insultarlo fa anche il # 1 in modo \xNN : reinterpreta le sequenze di \xNN come ottetti non codificati anziché trattarli come codepoint e li decodifica, impedendoti di esprimere caratteri al di fuori della codifica specificata e rendere il tuo codice sorgente significa cose diverse a seconda della codifica. È semplicemente sbalorditivo.

Scrivi il tuo codice sorgente solo in ASCII o UTF-8. In quest’ultimo caso, il pragma utf8 è la cosa giusta da usare. Se non si desidera utilizzare UTF-8, ma si desidera includere i caratteri non ASCII, sfuggire o decodificarli esplicitamente.

E usare i livelli di I / O in modo esplicito o impostarli usando il pragma open per fare in modo che l’I / O venga transcodificato automaticamente.

Funziona bene sul mio computer (su perl 5.10). Forse dovresti provare a sostituirlo use encoding 'utf8' con use utf8 .

Quale versione di Perl stai usando? Penso che le versioni precedenti avessero bug con UTF-8 in regexps.

La documentazione Test :: More contiene una correzione per questo problema, che ho appena trovato oggi (e questa voce è più alta nei google).

utf8 / “Carattere largo nella stampa”

Se usi utf8 o altri caratteri non ASCII con Test :: Altro, potresti ricevere un avviso di “caratteri larghi nella stampa”. Usando binmode STDOUT, “: utf8” non lo risolve. Test :: Builder (che alimenta Test :: Altro) duplica STDOUT e STDERR. Quindi qualsiasi modifica a loro, incluso il cambiamento delle loro discipline di uscita, non sembrerà da Test :: Altro. Il problema è cambiare i filehandle usati direttamente da Test :: Builder.

 my $builder = Test::More->builder; binmode $builder->output, ":utf8"; binmode $builder->failure_output, ":utf8"; binmode $builder->todo_output, ":utf8"; 

Ho aggiunto questo bit di boilerplate al mio codice di test e funziona in modo affascinante.