[SP-pm] Problema com encoding

Igor Sutton Lopes igor.sutton em gmail.com
Segunda Julho 23 03:32:10 PDT 2007


Wendel Scardua wrote:

[...]

> Se fosse assim isso aqui não aconteceria:
> 
> perl -e '%my_hash = ( ç  => 1)'
> Unrecognized character \xC3 at -e line 1.
> 
> Sendo que "ç" não é uma palavra composta. Se não me engano ele só vira 
> string se bate com o \w+ usual, que foi o que eu quis dizer com "ser um 
> identificador válido". Isto é, perl "estrito" não gosta que se use 
> barewords, mas é bonzinho se elas estiverem à esquerda do => .
> 
> Claro que isso é só um palpite meu baseado em observações, não em 
> documentação ^_^;;;

Isto está acontecendo por que você está utilizando um editor de textos 
utf8 e não está informando ao interpretador isto.

Tente:

<code>
use utf8;
%hash = ( ç   => 1 );
%hash = ( 'ç' => 1 );
</code>

Ah, importante: o que estamos discutindo não é se o perl é bonzinho ou 
não, mas sim o que ele pré-processa quando lê o nosso código fonte antes 
de gerar a árvore de operações.

Se você pegar o código acima e executar da seguinte maneira: perl 
-MO=Deparse teste.pl, você vai ter a seguinte saída:

<output>
C:\WINDOWS\system32\cmd.exe /c perl -MO=Deparse \temp\t.pl
use utf8;
use utf8 ();
(%hash) = ("\347", 1);
(%hash) = ("\347", 1);
\temp\t.pl syntax OK
</output>

Se você reparar bem nas linhas 4 e 5 do output, verá que independente do 
código ser diferente, o pré-processador age e transforma os dois na 
mesma instrução por quê ele *entende* que o caracter ç é um caracter 
multibyte válido.

Agora vamos ver sem o comando 'use utf8;':

<code>
%hash = ( 'ç' => 1 );
</code>

Você verá que a saída é diferente:

<output>
C:\WINDOWS\system32\cmd.exe /c perl -MO=Deparse \temp\t.pl
(%hash) = ("\303\247", 1);
\temp\t.pl syntax OK
</output>

Esta saída exemplifica bem os dois bytes que são utilizados para 
identificar um caractere em utf8.

Vamos modificar agora o encoding do arquivo e do editor para latin1 e 
executar o mesmo código:

<output>
C:\WINDOWS\system32\cmd.exe /c perl -MO=Deparse \temp\t.pl
(%hash) = ("\347", 1);
\temp\t.pl syntax OK
</output>

Bom, depois de tudo isso, testando com o encoding do arquivo como 
latin1, o trecho "%hash = ( ç => 1 );" não funciona, dando a seguinte 
mensagem:

<output>
C:\WINDOWS\system32\cmd.exe /c perl -MO=Deparse \temp\t.pl
Unrecognized character \xE7 at \temp\t.pl line 1.
shell returned 9
</output>

Acredito que isto aconteça por que o 'ç' não combine com \w+ a não ser 
com utf8...

Bom, cheguei até aqui. Alguém consegue continuar :-) ?




Mais detalhes sobre a lista de discussão SaoPaulo-pm