segunda-feira, março 30, 2009

case-insensitive e accent-insensitive no PostgreSQL

Gosto muito do PostgreSQL. Pessoalmente é um dos bancos que menos me causa o efeito "WTF", quando estou trabalhando com ele, com uma notável exceção... não tem nenhum parâmetro nem coisa parecida para poder fazer pesquisas case-insensitive e accent-insensitive. E isso é um grande "WTF" pra qualquer um que possua acentos na língua. Procurando uma solução, encontrei esses posts aqui: http://www.laudatio.com/wordpress/2008/11/05/postgresql-83-to_ascii-utf8/ http://www.mail-archive.com/pgsql-general@postgresql.org/msg112591.html http://www.postgresonline.com/journal/index.php?/archives/9-How-to-create-an-index-based-on-a-function.html Como meu banco é UTF-8, combinei elas em uma única solução:
CREATE OR REPLACE FUNCTION to_ascii(bytea, name)
RETURNS text STRICT AS 'to_ascii_encname' LANGUAGE internal;

CREATE OR REPLACE FUNCTION norm(a_string text)
RETURNS text AS $$
  BEGIN
    RETURN lower(to_ascii(convert_to(a_string, 'latin1'), 'latin1'));
  END
$$ LANGUAGE plpgsql
E como quando fazemos isso sempre precisamos de índice, em tese podemos criar os índices assim:
CREATE INDEX norm_tabela_campo_idx
  ON tabela
  USING btree norm(campo);

domingo, março 29, 2009

Sugestões para programar

Aqui tem uma lista de sugestões que eu uso quando estou programando. Faço questão de colocar elas para mim mesmo de uma maneira um tanto... "enfática", digamos assim. Descobri que quando fico indignado eu lembro melhor das coisas. Por isso, perdoe minhas "ênfases". Sugestão 1 Nomes significativos: pelo amor de JC e sua gangue, pare um pouco e coloque um nome decente nas coisas que faz (variáveis, métodos e classes). Sempre vale a pena colocar um bom nome, mesmo que isso custe vários minutos pensando. A razão disso? Crie um programa com nomes bem ruins e pouco significativos e depois tente dar manutenção nele, você vai lembrar do que eu disse agora. Sugestão 2 Indireção: use e abuse. Crie métodos a rodo, crie dezenas de classes pequenas, jogue o que puder para uma classe pai, abstraia ao máximo. O efeito disso é criar naturalmente Template Methods e DSLs, sem falar em diminuir a duplicação. Aliás, já repararam como template methods se parecem com micro DSLs? Sugestão 3 Valide o que vai usar para o método que está escrevendo. Se vai usar parâmetros, alguns "ifs" para validar que não está vindo lixo sempre são bemvindos. Se vai usar atributos, teste para ver se estão do jeito que você esperava encontrá-los. Se estiver com muita preguiça, mas muita mesmo, valide ao menos os nulos. Ah... e antes que eu me esqueça... NÃO, isso NÃO vai fazer seu programa ficar lento. Sugestão 4 Estado: se você está programando orientado a objeto. USE A PORRA DO ESTADO! Comece a computação em um método, termine em outro, jogue todas as variáveis possíveis para atributos. Se ficar com atributos de computações diferentes em uma única classe, use a dica 2. Se essa classe for compartilhada por múltiplas threads, não use essa sugestão. Sugestão 5 Pais? Sim, use muito classes pais, evite delegação. Ela dá um trabalho danado (principalmente se sua linguagem do coração não tiver proxies dinâmicos) e o benefício é mais teórico que prático. Ahhmm... mas todo mundo diz que é melhor usar delegação do que herança. Poisé, e eu estou dizendo o contrário. Você está programando orientado a objeto ou não, afinal? Delegação é boa sim, onde fizer sentido, como por exemplo, em wrappers. Sugestão 6 Não use cegamente sugestões e boas práticas. Sempre, sempre, sempre (eu falei SEMPRE, caralho!) conheça os prós e principalmente os contras de toda técnica que você vai usar. Boa prática só é boa se você sabe quando não deve usá-la. Isso vale especialmente para as sugestões que acabei de listar. ;) Que sugestões você colocaria na lista? Ou modificaria?

quarta-feira, março 25, 2009

Flamings e Einstein

É muito comum ver por aí nos fóruns de tecnologias alguns tópicos que são "flamings". Fiquei imaginando o que causam esses flames e como é difícil distinguir idéias completamente furadas das idéias que realmente tem algo de bom. Acho que consegui chegar em uma pequena fórmula que deve resolver parte do problema, ao menos para mim. O raciocínio veio quando estava lembrando do que fez Albert Einstein. O cara foi tão ponto fora da curva que criou sua teoria da relatividade de cabeça, não por que ele quis assim, mas porque simplesmente não havia (e acho que ainda não há) experimentos possíveis para provar que a idéia é verdadeira ou não. Aliás, no meio acadêmico, isso é bastante comum. Como ele fez isso (e aliás, como os cientistas fazem isso, normalmente)? Ele partiu de um "pressuposto" e começou a raciocinar em cima dele. No caso, o pressuposto é de que a luz possui velocidade constante. Matutando e pensando, ele chegou a conclusões incríveis... desde que a velocidade da luz seja constante. O que tem isso de importante? Bom, se provarem que realmente é uma constante (se já não provaram), é grande a chance de que toda a teoria esteja correta. Se provarem que não é constante, então toda a teoria vai pro brejo. Aí nossa opinião sobre a teoria da relatividade se resume a analisar 2 coisas: 1 - Se concordamos com o pressuposto; 2 - Se achamos que o raciocínio do cara não tem falhas lógicas. Em software temos um problema similar ao que tinha o tio Einstein. Temos grandes dificuldades de provar nossas idéias e teorias sobre software. Acho que daí nascem os flamings e todas essas discussões que ficam parecendo mais discussões religiosas do que discussões sobre uma ciência exata. Como em software não temos quase limitação nenhuma, quase qualquer idéia dá certo com o esforço suficiente aplicado, mesmo as idéias muito idiotas. Essas idéias, idiotas ou não, também são criadas a partir de pressupostos. Não sei se todos, mas todos os softwares, apis, frameworks e posts de blog que consigo lembrar são baseados em alguns pressupostos. O problema é que nunca deixamos claros quais pressupostos são esses. Então nossas idéias são analisadas a partir dos pressupostos que cada pessoa escolhe. Depende do que ele escolhe como pressuposto, sua opinião vai ser favorável ou não a nossa idéia. A "pequena fórmula" para resolver o problema dos flamings, e também o problema para se detectar uma idéia boa de uma idéia idiota é simplesmente deixar bem claro os pressupostos que se tomou para a idéia. Não, não foi dessa vez que descobri a América ou inventei algo novo e inédito, pelo visto. Mas para mim é um coisa que vem dando certo quando tenho que analisar algumas coisas, como Frameworks e posts de blogs. :) Querem ver um pequeno exercício? Você pode concordar ou discordar de tudo isso que eu disse, mas se ela é uma boa idéia ou não é mais fácil analisar se eu colocar os pressupostos aqui. Aí vão eles: - É comum flaming nos fóruns de tecnologia; - O que causa o flaming é a dificuldade de se separar idéias boas das ruins; - É difícil separar as idéias porque é difícil prová-las; - É difícil prová-las porque quase qualquer idéia sobre software funciona se aplicarmos esforço suficiente; - As pessoas tendem a analisar as idéias pelos seus próprios pressupostos; - Podemos separar as idéias se conhecermos claramente os pressupostos em que foram baseadas; Parece uma linha de raciocínio, mas na verdade não é. Cada linha da lista acima pode ser contestada facilmente e não pode ser provada, são pressupostos. Se você concordar com todos eles, provavelmente vai concordar com a minha teoria como um todo. Se deixar de concordar com qualquer uma delas, provavelmente vai achar minha teoria um lixo. Se todos eles puderem ser provados com sucesso, então a teoria é verdadeira. Se qualquer um deles for provado em contrário, então ela é furada. Com tantos pressupostos (são ao menos seis, se não esqueci nada), dá pra ver que essa minha idéia é bem frágil. Bom, agora você conhece a teoria e conhece claramente no que me baseei para montá-la. Espero que fique fácil analisar se ela tem fundamento ou não para você e o porquê disso. E aí? Tem fundamento?