terça-feira, 11 de janeiro de 2011
Agenda da CP 2011
Mas descobri (na página http://www.universotech.com/campus-party-brasil/confira-tudo-que-vai-rolar-na-campus-party-brasil-2011/) que basta colocar um iframe com o src apontando pro Google Agenda que dá pra acessar no mesmo formato da página oficial da CP. Aproveitem!
sexta-feira, 2 de abril de 2010
O Mínimo Absoluto que Cada Desenvolvedor de Software Deve Obrigatoriamente Saber Sobre Unicode e Conjuntos de Caracteres (Sem Desculpas!)
Esse é um artigo sobre Unicode, charsets, etc. que eu achei esses dias.
Antes de eu começar, devo avisá-lo que se você é uma das raras pessoas que conhece internacionalização, você irá achar minha explicação um pouco simplificada demais. Eu estou apenas tentando fazer um alinhamento mínimo para que todos possam entender o que está acontecendo e poder escrever algum código que tenha alguma esperança de funcionar com texto em qualquer linguagem que não o subgrupo de inglês que não inclui palavras com acentos. E devo avisá-lo que o tratamento de caracteres é apenas uma pequena parte do necessário para se criar um software que funcione internacionalmente, mas eu só posso escrever uma coisa de cada vez, assim, hoje serão conjuntos de caracteres.
Uma Perspectiva Histórica
A maneira mais fácil de entender esse assunto é avançando cronologicamente.
Você provavelmente está pensando que irei falar de conjunto de caracteres muito antigos como EBCDIC aqui.
Bem, eu não irei. EBCDIC não é relevante para sua vida. Não precisamos voltar no tempo tanto assim.
De volta aos tempos semi-antigos, quando o Unix estava sendo inventado e K&R estavam escrevendo The C Programming Language, tudo era bastante simples. EBCDIC estava saindo. Os únicos caracteres que realmente importavam eram as boas letras não acentuadas do inglês, e tínhamos um código para elas chamado ASCII que era capaz de representar qualquer caractere usando um número entre 32 e 127. Espaço era igual a 32, a letra "A" era 65, etc. Isto podia ser convenientemente armazenado em 7 bits. A maioria dos computadores daquela época usava bytes de 8 bits, então você não só apenas podia guardar cada possível caractere ASCII, mas também tinha um bit excedente, que, caso você fosse perturbado, poderia usar para seus propósitos doentios: os seres obtusos do WordStar usaram o bit mais alto para indicar a última letra de uma palavra, condenando o WordStar a editar apenas textos em inglês. Códigos abaixo de 32 eram chamados não-imprimíveis e eram usados em xingamentos. Brincadeira. Eles eram usados como caracteres de controle, como o 7 que fazia seu computador bipar e o 12 que fazia a página atual da impressora sair da impressora e uma nova folha ser pega.
E estava tudo bem, desde que você falasse inglês.
Pelo fato de os bytes terem espaço para 8 bits, um monte de gente começou a pensar, "Nossa, nós podemos usar os códigos 128-255 para nossos próprios assuntos". O problema foi que um monte de gente teve essa idéia ao mesmo tempo, e elas tinham suas próprias idéias sobre o que deveria ficar no espaço entre 128 a 255. O IBM-PC tinha uma coisa que veio a ser conhecida com o conjunto de caracteres OEM que disponibilizava alguns caracteres acentuados para línguas européias e um monte de caracteres para desenhar linhas... barras horizontais, barras verticais com pequenos penduricalhos balançando do lado direito, etc., e você poderia usar esses caracteres de desenhos de linhas para fazer caixas e linhas bem apresentáveis na tela, que você ainda podia ver rodando no computador 8088 em suas lavadoras a seco. De fato quando as pessoas começaram a comprar PCs fora dos Estados Unidos todos os tipos de diferentes conjuntos de caracteres OEM foram inventados, e todos eles usavam os maiores 128 caracteres para seus próprios objetivos. Por exemplo, em alguns computadores o código 130 iria ser exibido como "é", mas em computadores vendidos em Israel havia a letra hebréia Gimel (), daí quando americanos enviassem seus currículos (résumés, em inglês) para Israel eles chegariam como
Eventualmente esse OEM livre para todos foi codificado no padrão ANSI. No padrão ANSI, todos concordaram sobre o que fazer abaixo de 128, que era quase o mesmo que ASCII, mas haviam muitas maneiras diferentes de lidar com os caracteres acima de 128, dependendo de onde você vivesse. Esses diferentes sistemas eram chamados de páginas de códigos. Então, por exemplo, em Israel, o DOS usava uma página de código chamada 862, enquanto usuários gregos usavam a 737. Elas eram iguais nos caracteres abaixo de 128, mas diferentes acima de 128, onde todas as letras diferentes ficavam. As versões nacionais do MS-DOS tinham dúzias dessas páginas de códigos, lidando com tudo, desde inglês até islandês, e eles tinha algumas páginas de código "multilíngua" que podiam entender Esperanto e Galiciano no mesmo computador! Wow! Mas ter, por exemplo, hebreu e grego no mesmo computador era uma total impossibilidade a menos que você escreve seu próprio programa customizado que mostrasse tudo usando gráficos bitmap, pois Hebreu e Grego requeriam diferentes páginas de códigos com diferentes interpretações dos números altos.
Enquanto isso, na Ásia, coisas mais malucas estavam acontecendo, levando em conta o fato que os alfabetos asiáticos têm milhares de letras, que nunca caberiam em 8 bits. Isso era normalmente resolvido pelo confuso sistema chamado DBCS, o "conjunto de caracteres com duplo byte" no qual algumas letras eram armazenadas em um byte e outras em dois. Era fácil se mover para frente em uma string, mas quase impossível se mover para trás. Os programadores eram encorajados a não usar s++ e s-- para se moverem para frente e para trás, mas ao invés disso chamar funções como AnsiNext e AnsiPrev do Windows que sabiam como lidar com toda essa confusão.
Mas ainda assim, a maioria das pessoas apenas achava que um byte era um caractere e um caractere era 8 bits e desde que você nunca movesse uma string de um computador para outro, ou falasse mais de uma língua, isso meio que iria sempre funcionar. Mas é claro, assim que a Internet aconteceu, mover strings de um computador a outro se tornou um pouco mais comum, e toda uma confusão surgiu. Afortunadamente, o Unicode foi inventado.
Unicode
O Unicode foi um bravo esforço para criar um único conjunto de caracteres que incluíam cada sistema de escrita razoável no planeta e alguns de faz-de-conta como Klingon, também. Algumas pessoas ainda têm a falsa idéia de que Unicode é apenas um código de 16 bits onde cada caractere tem 16 bits e existem 65.536 caracteres possíveis. Na verdade, isso não está correto. Este é simplesmente o mito mais comum sobre Unicode, então se você pensava isso, não se sinta mal.
De fato, Unicode tem uma maneira diferente de pensar sobre caracteres, e você deve entender a maneira Unicode de pensar nas coisas ou nada fará sentido.
Até agora, nós assumimos que uma letra é codificada em alguns bits que podem ser gravados em disco ou em memória.
A -> 0100 0001
Em Unicode, uma letra é codificada em algo chamado código único (code point, no original), que é apenas um conceito teórico. Como este código único é representado em memória ou disco é uma história completamente diferente
Em Unicode, a letra A é um ideal platônico. Está apenas flutuando no paraíso:
Este A platônico é diferente de B, e diferente de a, mas a mesma coisa que A e A e A.
A idéia de que um A na fonte Times New Roman é o mesmo caractere que o A na fonte Helvetica, mas diferente de um "a" minúsculo não parece muito controversa, mas em algumas linguagens apenas descobrir o que uma letra é pode causar controvérsia. A letra alemã ß é uma letra real ou uma maneira enfeitada de escrever ss? Se a forma de uma letra muda no fim de uma palavra, ela se torna uma letra diferente? Hebreus dizem sim, árabes dizem não. De qualquer maneira, os caras espertos do consórcio Unicode têm entendido isso durante a última década, acompanhados de uma grande porção de debates políticos, e você não precisa se preocupar com isso. Eles já entenderam tudo.
Cada letra platônica em cada alfabeto é atribuída a um número mágico pelo consórcio Unicode que é escrito dessa maneira: U+0639. Este número mágico é chamado de código único. O U+ significa "Unicode" e os números são hexadecimais. U+0639 é a letra arábica Ain. A letra inglesa A seria U+0041. Você pode achar todas elas usando o utilitário charmap no Windows 2000/XP ou visitando o web site do Unicode.
Não há um real limite no número de letras que o Unicode pode definir e de fato eles foram além de 65.536, então nem todas as letras Unicode podem realmente ser espremidas em dois bytes, mas isso era um mito de qualquer maneira.
OK, então nós temos uma string:
Codificações
É aqui que as codificações entram.
A idéia mais antiga para a codificação Unicode, que levou ao mito sobre os dois bytes, era, ei, vamos apenas guardar esses números em 2 bytes cada. Então Hello se torna
Por um tempo pareceu que isso seria bom o bastante, mas os programadores reclamavam. "Olhem todos esses zeros!", diziam eles, pois eles eram americanos e estavam olhando textos em inglês que raramente usavam códigos acima de U+00FF. Além disso, eles eram hippies liberais da Califórnia. Se eles fossem texanos eles não se importariam em aceitar o dobro número de bytes. Mas aqueles fracotes californianos não podiam tolerar a idéia de dobrar a quantidade de armazenamento para strings, e de qualquer maneira, já existiam muitos documentos por aí usando várias codificações como ANSI e DBCS e quem iria converter todos eles? Eu? Por essa razão muitas pessoas decidiram ignorar o Unicode por vários anos e enquanto isso as coisas pioraram.
Dessa forma, foi inventado o brilhante conceito de UTF-8. UTF-8 era outro sistema para armazenamento de strings de códigos Unicode - aqueles números U+ mágicos - em memória usando bytes de 8 bits. Em UTF-8, cada código de 0 a 127 é armazenado em um único byte. Apenas os códigos acima de 127 são guardados usando 2, 3, e de fato, até 6 bytes.
Isso tinha a perfeita consequência de textos em inglês ficarem em UTF-8 exatamente do mesmo jeito que ficavam em ASCII, então os americanos nem mesmo perceberam algo errado. Apenas o resto do mundo teve se virar. Especificamente, Hello, que era igual a U+0048 U+0065 U+006C U+006C U+006F, seria guardado como 48 65 6C 6C 6F, que, contemplem!, é igual ao que era guardado em ASCII, e ANSI, e qualquer conjunto de caracteres OEM no planeta. Agora, se você é corajoso o suficiente para usar letras acentuadas ou letras gregas ou em Klingon, você tera que usar vários bytes para guardar um simples código UTF, mas os americanos nunca reparariam (UTF-8 também tem uma propriedade legal em que velhos processadores de strings ignorantes que queiram usar o byte 0 como null-terminator não truncarão strings).
Até agora eu lhe contei três maneiras de codificar Unicode. Os métodos tradicionais de armazenamento em dois bytes são chamados de UCS-2 (porque são 2 bytes) ou UTF-16 (porque são 16 bits), e você ainda tem que calcular se ele é UCS-2 high-endian ou low-endian. E há o popular e novo padrão UTF-8 que tem a boa propriedade de trabalhar respeitavelmente se você passar pela feliz coincidência de textos em inglês e programas descerebrados que estão completamente desavisados que existe alguma coisa além de ASCII.
Atualmente, existem um monte de outras maneiras de codificar Unicode. Há algo chamado UTF-7, que é muito parecido com UTF-8, mas garante que o maior bit sempre será zero, então, se você precisa enviar Unicode através de algum sistema de segurança de e-mail draconiano que pensa que 7 bits são o suficiente, obrigado você ainda pode ainda pode espremê-lo incólume. Há o UCS-4, que guarda cada código em 4 bytes, que tem a propriedade de cada código poder ser guardado no mesmo número de bytes, mas, céus!, nem mesmo os texanos seriam tão ousados a ponto de gastarem tanta memória.
E de fato, agora que você está vendo as coisas em termos de letras ideais platônicas que são representadas por códigos Unicode, estes códigos Unicode podem ser codificados em qualquer esquema de codificação mais antigo. Por exemplo, você poderia codificar a string Unicode Hello (U+0048 U+0065 U+006C U+006C U+006F) em ASCII, ou no velho OEM grego, ou na codificação ANSI-Hebreu, ou qualquer uma das várias centenas de codificações que foram inventadas até agora, com um complicador: algumas das letras podem não aparecer! Se não houver nenhum equivalente para o código Unicode que você está tentando representar na codificação em que você está tentando representá-lo, você normalmente conseguirá um ponto de interrogação: ? ou, se você for realmente bom, um quadrado. Qual que você conseguiu? -> �
Há centenas de codificações tradicionais que podem armazenar apenas alguns códigos corretamente e transformam todos os outros códigos em interrogações. Algumas codificações populares para textos em inglês são o Windows-1252(O padrão Windows 9x para línguas da Europa Ocidental) e ISO-8859-1, também conhecido como Latin-1 (também útil para qualquer língua da Europa Ocidental). Mas tente armazenar letras hebréias ou russas nessas codificações e você conseguirá um monte de interrogações. UTF 7, 8, 16 e 32 têm a bela propriedade de serem capazes de armazenar qualquer código corretamente.
O Fato Mais Importante Sobre Codificações
Se você esqueceu completamente tudo o que eu expliquei, por favor, lembre de um fato extremamente importante. Não faz nenhum sentido ter uma string sem conhecer qual codificação ela usa. Você não pode mais enfiar sua cabeça no chão e achar que texto "plano" é ASCII.
Quase todos os problemas estúpidos como "meu website mostra um monte de coisas sem sentido" ou "ela não pode ler meus e-mails quando uso acentos" vêm de um programador ingênuo que não entendeu o simples fato de que se você não disser se uma string está codificada usando UTF-8, ASCII, ISO 8859-1 (Latin 1) ou Windows 1252 (Europeu Ocidental), você simplesmente não poderá mostrá-la corretamente ou nem mesmo saber onde ela termina. Existem centenas de codificações e acima do código 127, todas as apostas são arriscadas.
Como você mantém essa informação sobre qual codificação uma string usa? Bem, existem formas padrões de se fazer isso. Para uma mensagem de e-mail, é esperado que haja uma string no cabeçalho na forma
Content-Type: text/plain; charset="UTF-8"Para uma página da Web, a idéia original era que o servidor Web retornaria um cabeçalho HTTP Content-Type similar juntamente com a página - não no HTML, mas em um dos cabeçalhos de resposta que são enviados antes da página HTML.
Mas isso acarreta alguns problemas. Suponha que você tenha um grande servidor Web com muitos sites e centenas de páginas mantidas por várias pessoas em diferentes línguas e usando qualquer codificação em que a cópia do Microsoft FrontPage que eles tinham achasse adequado para gerar a página. O servidor Web sozinho não sabe realmente em qual codificação cada arquivo foi escrito, então ele não poderia enviar o cabeçalho Content-Type.
Seria conveniente se você colocasse o Content-Type do HTML juntamente com o arquivo HTML, usando algum tipo de tag especial. É claro que isso deixou os puristas malucos... como você poderia ler o arquivo HTML sem saber em qual codificação ele está?! Por sorte, quase todas as codificações em uso comum fazem as mesmas coisa com os caracteres entre 32 e 127, então você sempre consegue chegar nessa parte do HTML sem usar letras diferentes:
<html>Mas essa meta tag realmente deve ser a primeira coisa na seção <head> por que quando o navegador web vê essa tag ele irá parar de processar a página e começará de novo após reinterpretar a página inteira usando a codificação que você especificou.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
O que os navegadores web fazem se não acham nenhum Content-Type, seja nos cabeçalhos HTTP ou nas meta tags?
O Internet Explorer faz algo um tanto quanto interessante: ele tenta adivinhar, baseado na frequência em que vários bytes aparecem em textos típicos em codificações típicas de várias linguagens, qual linguagem e qual codificação está sendo usada. Pelo fato de várias páginas código antigas de 8 bits tenderem a colocar suas letras nacionais em diferentes limites entre 128 e 255, e desde que cada linguagem humana tem diferentes historigramas característicos de uso de letras, isso tem uma chance de funcionar.
É realmente estranho, mas parece funcionar o suficiente para que até mesmo desenvolvedores web ingênuos que nunca souberam que precisavam de um cabeçalho Content-Type olhem para suas páginas em um navegador e vejam tudo ecer corretamenteetam, até que, um dia, eles escrevem algo que não se adequa exatamente à frequência de distribuição de letras de sua língua nativa, e o IE decide que o texto é coreano e o mostra dessa maneira provando, penso eu, a idéia de da Lei de Postel sobre ser "conservador no que você emite e liberal no que aceita" não é um conselho de engenharia muito bom.
De qualquer maneira, o que faz o pobre leitor desse website, que foi escrito em búlgaro, mas parece ser coreano (e nem mesmo um coreano coeso)? Ele usa o menu Exibir | Codificação e tenta um monte de diferentes codificações (existem pelo menos uma dúzia para as línguas da Europa Oriental) até o texto aparecer claramente. Se, e somente se, ele souber disso, o que a maioria não sabe.
Na última versão do rsão do CityDesk, o software de manutenção de web sites publicado pela minha companhia, nós decidimos fazer tudo internamente em UCS-2 (dois bytes) Unicode, que é o que o Visual Basic, o COM, e o Windows NT/2000/XP usam como seus tipos string nativos. Em códigos C++ nós apenas declaramos strings como wchar_t ("wide char") ao invés de char e usamos a função wcs ao invés das funções str (por exemplo, wcscat e wcslen ao invés de strcat e strlen). Para criar uma string UCS-2 literal em C você apenas coloca um L antes dessa maneira: L"Hello".
Quando o CityDesk publica a página web, ele a converte para a codificação UTF-8, que é bem suportada pelos navegadores web há muitos anos. É dessa maneira que todas as 29 versões de idiomae idioma do Joel on Software são codificadas, e eu ainda não ouvi uma única pessoa que teve algum problema visualizando-as.
Esse artigo está ficando particularmente longo, e eu não posso cobrir tudo o que há para saber sobre codificações de caracteres e Unicode, mas eu acredito que se você chegou até aqui, você sabe o suficiente para voltar a programar, usando antibióticos ao invés de sanguessugas e feitiços, uma tarefa que deixo para você agora.
sábado, 13 de fevereiro de 2010
Metal – A HeadBangers Journey
Eu acabei de assistir um documentário, produzido pelo canadense Sam Dunn, formado em Antropologia e amante de Heavy Metal, que se propôs a explicar o que é o Metal, suas origens, vertentes, e o porquê de seus fãs terem sido considerados a escória da sociedade por décadas.
Uma coisa bem surpreendente é o fato de ele ter conseguido entrevistas com grandes personalidades da história do Rock, como Bruce Dickinson, Geddy Le, Lemmy (Motorhead), Dio, cobrindo alguns assuntos bem legais.
Outra coisa que eu achei bem interessante foi uma árvore com todas as vertentes do Metal, desde o Early Metal, até os galhos mais distantes, como o Death Metal e o Glam Metal. Embora o documentário não se aprofunde ao extremo em todos os nós dessa árvore, vale como um mapa geral do metal, na minha opinião.
Agora, a coisa que mais me chamou a atenção em todo o documentário, e, nesse ponto, talvez alguns leitores me achem tolo ou algo assim, foi o sentimento em relação ao metal.
Eu me identifiquei muito em algumas entrevistas com fãs, como por exemplo:
“A maioria dos metalheads, se lhes dizem algo, têm suas próprias opiniões e podem dizer: "Isto é o que penso". Não tratam de ouvir a mesma música que ouvem seus amigos, não tratam de ouvir o que está na moda para ser aceito. É o que encontra no metal: confiança, porque é uma música forte, que te dá a habilidade de parar e dizer: "Ok. Dane-se!"”
Agora, o comentário que mais explodiu minha cabeça foram as palavras finais do Sam no final do documentário, durante o festival de Wacken, na Alemanha:
“Desde que tinha 12 anos, tive que defender meu amor pelo heavy metal contra quem o classificasse de forma de música "barata". Minha resposta agora é que ou se sente o metal ou não. Se o metal não te provoca essa envolvente sensação de poder, e não faz com que se arrepiem os cabelos da nuca, talvez, nunca o compreenda. E sabe o que mais? Tá tudo OK. Porque, a julgar pelos 40.000 metalheads que me rodeiam, estamos bastante bem sem você.”
Depois dessa fala aí, com Master of Puppets tocando ao fundo, eu não tenho mais nada a dizer.
Site Oficial do documentário: http://www.metalhistory.com/
sábado, 21 de novembro de 2009
Como não odiar a Google pt. 1
Bom, estava eu hoje, calmamente boiando em uns blogs por aí (mais exatamente aqui - http://www.nowloading.com.br/altair-no-mundo-real) , quando clico em um link pra um vídeo do Youtube e... PÁÁ! Erro 500! Que inferno! Por alguns segundos, meu sangue aumentou de temperatura, comecei a tremer, o olho direito começou a piscar sem parar de raiva, quando eu chego na terceira linha da página de erro:
Depois de uma página de erro dessas, eu não consigo ficar com raiva de quem fez isso... queria colocar umas mensagens assim no software da minha empresa... LOL