[Cascavel-pm] Uso de encode/decode para tratar Unicode

Daniel Ruoso daniel em ruoso.com
Quarta Janeiro 10 02:50:22 PST 2007


Ter, 2007-01-09 às 18:16 -0200, Nilson Santos Figueiredo Junior
escreveu:
> On 1/9/07, Daniel Ruoso <daniel em ruoso.com> wrote:
> > Ainda de forma resumida, qualquer chamada explicita a encode ou decode
> > demonstra que você está indo pelo caminho errado.
> Daniel, gostaria que, se possível, você elaborasse mais sobre o assunto.
> Recentemente, precisei de realizar algumas chamadas explícitas não
> exatamente aàs funções encode/decode mas à função utf8::upgrade().

Acho que o seu problema mostra exatamente o motivo para não utilizar
encode/decode diretamente. O que acontece é que a forma como o perl
entende se uma string é unicode ou não é através de uma flag na
estrutura da variável que é uma string.

O que acontece é que manipular isso diretamente é confuso, uma vez que
iria exigir que você fique checando e manipulando para fazer os
encodes/decodes... o que é mau... :)...

A vantagem é que o Perl cuida de tudo desde que você trate das coisas
corretamente.

> O problema é que os dados retornados pela função LWP::Simple::get()
> não estão marcados como UTF8, apesar de serem UTF8. Isso me causava
> diversos problemas e o uso da função utf8::upgrade() foi uma solução
> que eu encontrei. Se tiver alguma outra forma melhor de fazer isso, eu
> ficaria muito feliz em saber, já que não sou nenhum expert nesses
> assuntos sobre encodings.

O que está acontecendo aqui é que o método LWP::Simple tem um bug, ele
deveria utilizar o método $response->get_decoded() ao inves de
simplesmente $response->get() (veja HTTP::Response).

Veja bem que protocolos de comunicação de rede são o caso onde a
resposta resumida não cabe, por que a princípio não se sabe qual o
encoding. No entanto, o próprio protocolo já define uma maneira de
informar o encoding corretamente (neste caso o HTTP). Então, dessa
forma, é responsabilidade do módulo que gerencia o protocolo encapsular
o caso que não cabe na resposta resumida (nesse caso, o HTTP::Response,
que o faz, mas o LWP::Simple está ignorando esse tratamento).

No caso do código que você apresentou, existem duas possibilidades: a
primeira é submeter o bug ao LWP::Simple e esperar que ele seja
corrigido para poder tirar o utf8::upgrade() do seu código. A outra é
submeter o bug ao LWP::Simple, mas usar diretamente o LWP::UserAgent e
chamar o método correto do objeto HTTP::Response.

Agora, se o servidor que você está usando não dá a resposta sobre o
encoding corretamente, bem, aí temos um outro problema que quem vai ter
que tratar é o seu módulo mesmo (mas submeter o bug ao site para que
eles corrijam). Mas existem Meta-tags no html para definir o encoding do
conteúdo que podem ser observadas pelo parser do HTML.

Mas, de todas essas opções, fazer utf8::upgrade() cegamente é a opção
mais frágil, mas o único workaround possível no caso do site do outro
lado não estiver seguindo as regras corretamente.

Espero que tenha conseguido ajudar,

Daniel



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