Acorda pra Web!

Tecnologia que vai mudar nossas vidas, depois do café.

Arquivo de July, 2007

Meu framework não será MVC

Tuesday, July 31st, 2007

Não totalmente, não esse falso MVC por aí. Em todos os frameworks pra web há um engano conceitual profundo: O View é o HTML.

Por definição, View é a parte da apresentação da aplicação, é a renderização para o usuário do Model. Trocando em miúdos, é aquela coisa que mostramos pro usuário.

Há 10 anos atrás, talvez colocar o HTML como View talvez fosse a melhor saída, mas hoje o HTML é definido como uma camada de informação, não de apresentação.  O HTML tem conteúdo, tem significado, é semântico.

Pensando por esse lado, o HTML está mais próximo do Model do que do View. Um site estático cheio de páginas HTML e um arquivo CSS pra todas também é um framework MVC, o Model é o HTML, o View é o CSS e o Controller é o sistema de arquivos do servidor.

Pode parecer extremamente sujo misturar bancos de dados com HTML, mas não é disso que estamos falando. É possível manter o HTML separado do banco de dados, como uma camada intermediária entre o Model e o View. É um pre-view post-model. Como se não bastasse, o HTML também é Controller, com formulários e links.

Ainda não descobri como resolver o problema do HTML, não posso simplesmente jogar a resposta do banco de dados na página e usar CSS nela. A solução ideal seria usar XSLT como camada intermediária entre o banco de dados e o HTML, mas ele é complicado demais para tornar o framework um facilitador. Imagino que no final, o HTML ficará como uma camada de Model-template.

Web Semântica – Ensinar a maior criança do mundo a escrever seu nome

Monday, July 23rd, 2007

A menos que você seja hiperléxico, como William James Sidis, durante os seus primeiros anos de vida você via as palavras que as pessoas escreviam mais ou menos assim: #$%*@$%#$#&*, como belíssimas figuras sem significado algum. Baseado nesse princípio, pesquisadores estão tentando desenvolver sistemas para Web Semântica.

É exatamente isso que os computadores vêem, um monte de figuras (na verdade bits) sem significado algum, ou muito pouco significado. O poder de processar informações é limitadíssimo. Você pode até “perguntar” para um computador com um determinado banco de dados o telefone de algumas pessoas cadastradas, por exemplo, mas isso é tão primitivo quanto uma criança que escreve o R espelhado, o que nem sempre é uma criança, pode ser algum membro do orkut querendo enfeitar seu miguxês.

As tentativas de fazer um computador ler coisas como “Roberto” (@#$%&*) são muitas, entre elas tem uma muito especial no campo da semântica, o XML: <pessoa>@#$%&*</pessoa>. Olha que brilhante! Agora o computador sabe que @#$%&* é uma pessoa? Não exatamente… ele no máximo vai enxergar isso dessa forma: <##$*>@#$%&*</##$*>, e saberá que quando você escrever “pessoa”, é aquela figurinha que ele tem que buscar no baú, a ##$*. Se você pedir um indivíduo, ou um humano, ele voltará a estaca zero.

Basicamente, o esforço atual não é tentar fazer o computador ler a linguagem que nós escrevemos, mas é uma mistura disso com o esforço do XML. Através de vocabulários e ontologias, desenvolvedores estão tentando fazer com que uma máquina veja essas “figuras” (que pra nós são palavras) de uma maneira muito mais completa, podendo diferenciar e relacionar uma coisa de outra coisa.

Parece bem estúpido, mas pra um computador é extremamente difícil dizer a diferença entre uma banana e uma maçã. Ele pode até dizer que a palavra “banana” é diferente da palavra “maçã”, ou no máximo, com muito esforço, dizer que a cor da banana é amarela e a maçã vermelha, ou talvez ele diga #F00. Se o computador ao ver a palavra “banana” puder acessar um rico banco de dados contendo informações como “banana é uma fruta”, “banana é amarela”, “banana vende por dúzia”, será muito mais provável que ele consiga comparar essas informações com o banco de dados “maçã” e estabelecer as diferenças. Esses grandes bancos de dados sobre diversas coisas são as ontologias.

Esse é basicamente o conceito de Web Semântica, e talvez no futuro perguntar coisas para um computador seja tão trivial quanto fazer consultas ao Google. Primeiro o que temos que fazer é ensinar essa internet grandona a escrever, copiando as nossas figuras ;)

Coisóides abstratos para internet

Thursday, July 19th, 2007

Hoje em dia é bem simples encontrar qualquer sistema pra internet. Você tem dezenas de softwares concorrentes pra montar cadastro de clientes, controle de finanças, lojas virtuais, sistemas de notícias, blogs, controle de funcionários, gerenciamento de projetos, fóruns, sistemas de newsletter e por aí vai.

O grande problema de tudo isso é que são ótimos aplicativos separados, péssimos em conjunto. Você não pode simplesmente pegar uma loja virtual com 500 clientes cadastrados, instalar um aplicativo de newsletter e aproveitar os emails dos clientes já cadastrados na loja automaticamente. Você tem que adaptar bancos de dados, scripts de configuração e tudo mais. É um saco. Esse problema gera sotwares gigantescos, com complexidade desnecessária e tão cheios de tantos propósitos que acabam ficando sem propósito específico.

O último software desse estilo que vi foi o Weblawyer, que serviu para pesquisas no desenvolvimento de um sistema de controle processual para um dos meus clientes. Advogados trabalham diretamente com processos, leis, fóruns e por aí vai, no entanto o Weblawyer possui controle de finanças, clientes, empresas, usuários do sistema.

Dois desses módulos, o controle de finanças e o de usuários do sistema, são potencialmente desnecessários, não é qualquer escritório que irá utilizá-los, principalmente o controle de finanças que embora seja bom, possui sotwares específicos muito melhores para esse fim.

Nisso, voltamos ao velho problema. Eu não posso simplesmente pegar o Weblawyer e integrar com esse sistema de despesas feito pelo Nelson Salvador. São dois sistemas completamente incompatíveis à princípio.

É por isso que é necessário que sejam desenvolvidos sistemas abstratos, plugáveis, modulares. Um sistema plugável de cadastro de clientes que possa ser usado para qualquer outro sistema que trabalhe com clientes, um sistema abstrato de despesas que possa ser usado para qualquer sistema que trabalhe com dispesas. No final, você apenas coloca todos na pasta e pronto, tem o que você quer. Quando é que vão surgir coisas assim?!

Freebase, quase lá, quase

Monday, July 16th, 2007

O Freebase pra mim era o projeto que faltava no campo da web semântica. É como um enorme banco de dados em formato de Wikipedia.

O negócio é realmente impressionante. Eles importam conteúdo de diversos outros sistemas e organizam os recursos uniformemente.

Também há como criar e alterar conteúdo manualmente, assim, se o sistema definir que Helloween é uma marca de mostarda ao invés de uma banda, você pode corrigí-lo.

Ao invés do modelo centrado em títulos da Wikipedia, o Freebase é centrado em tipagem. Se você fizer uma busca por “Semantic”, que pode ser uma banda, ou um disco, ou relacionado a uma tecnologia da internet, você pode filtrar os resultados por tipo.

O campo de filtro fornece constantemente sugestões. Se você quer buscar rapidamente pessoas relacionadas ao termo “Ferrari”, basta buscar por Ferrari e adicionar o filtro “Person”. O irônico é que alguns tópicos ainda não estão tipados, se você buscar por “Ferrari” com filtro “Carro”, não encontrará resultados, porque os artigos sobre carros não foram tipados ainda :)

O Freebase tem como alvo também desenvolvedores. A API deles permite que você faça buscas no sistema inteiro como se fosse um banco de dados, com a MQL, uma linguagem própria deles.

O sistema tem grande potencial, mas ainda é imaturo. Não faz buscas fonéticas ou com palavras similares, por exemplo. Além disso, depende bastante de usuários humanos para edição e organização, o que retarda o desenvolvimento, já que os usuários mais ativos em colaboração preferem projetos consolidados como a Wikipedia.

É possível também enviar dados para o Freebase de qualquer aplicação, mas a interface é completamente diferente do que conhecemos. Embora trabalhe com JSON, o formato não é muito familiar com os modelos de outros bancos de dados, o que desestimula novos desenvolvedores.

Bom mesmo seria se existisse uma maneira de simplesmente absorver metainformação da Wikipedia diretamente.

A maior linha de código

Saturday, July 14th, 2007

Será que no livro dos recordes existe a maior linha de código já escrita? Eu costumo escrever linhas grandes, sou fã de expressões e inevitavelmente elas levam a isso.

No PHP, expressões ajudam bastante a economizar código. Por exemplo, os três trechos abaixo verificam se a variável “var” é numérica, se não for abortam o script:

PHP
if (!is_numeric($var)) {
die;
}

PHP
if (!is_numeric($var)) die;

PHP
is_numeric($var) or die;

O terceiro trecho é simples, é uma expressão binária or. Se a primeira expressão for válida, ele não verifica a segunda. Se a primeira for inválida, ele verifica a validade da segunda. Você só pode fazer esse tipo de expressão com funções que retornam valores, como a die que eu utilizei. Você não pode por exemplo fazer isso:

PHP
is_numeric($var) or return(FALSE);

Return é uma estrutura de linguagem que não retorna valores dentro de uma expressão (retorna eles externamente), portanto não pode ser uma expressão válida e gera um erro.

Outro recurso interessante são as expressões ternárias:

PHP
is_numeric($var) ? print('Ok! Numérico') : die; 

Esse trecho acima equivale ao seguinte:

PHP
if (is_numeric($var)) {
print('Ok! Numérico');
} else {
die;
}

A síntaxe básica é condição ? verdadeiro : falso. Simples e prático, né?

Ah, a maior linha que eu escrevi até hoje foi essa:

PHP
if ($mirror = new ReflectionMethod($obj[0], $obj[1])) $mirror->getStartLine() == $mirror->getEndLine() ? $this->_call(array($obj[0], $obj[1].ucfirst(empty($args[0]) || ($met = !method_exists($this, $obj[1].ucfirst($args[0]))) ? 'index' : $args[0])), $met ? $args : array_slice($args, 1)) : call_user_func_array($obj, $args);

Essa única linha ilegível e complexa (acredite, gosto disso) cria um objeto refletor, verifica se o método chamado é vazio em uma classe e chama um outro método com nome variável com base nos argumentos passados para o método vazio. Caso o método vazio seja passado sem argumentos ele chama um método-índice.

Em outras palavras, ela transforma uma chamada de cliente(’incluir’,'Alexandre) em clienteIncluir(’Alexandre’) automaticamente, caso a chamada seja cliente() ele transforma em clienteIndex().

Essa linha faz parte do controlador do meu novo framework, se quiserem usar podem, com algumas condições.

Persistência de objetos

Wednesday, July 11th, 2007

Desde que comecei a escrever meu próprio framework venho buscando maneiras mais eficientes de programar. Obviamente, além das minhas próprias idéias, grande parte das minhas inspirações vêm de sistemas já existentes, frameworks que já funcionam muito bem.

Uma coisa que venho notado, é que algumas funcionalidades viraram moda em determinados frameworks, e ninguém tenta criar algo ainda mais eficiente.

O ActiveRecord por exemplo é um padrão de desenvolvimento que ainda é completamente confuso pra mim. Entendo bem de SQL e de programação em PHP, mas o ActiveRecord não é exatamente nem um nem outro, é uma terceira camada de lógica completamente diferente.

Um dos grandes problemas dele é que não funciona bem com bancos que não sigam o padrão determinado pelo padrão. Uma das coisas que boa parte das implementações do ActiveRecord exige é que toda tabela tenha um campo id numérico como chave primária, o que não acontece em 100% dos casos da vida rea.

Em muitos métodos dos objetos do padrão há mistura de coisas da lógica da linguagem com a lógica do banco, uma péssima prática.

De qualquer maneira, minha proposta não é exclusivamente criticar outros padrões, estou tentando criar algo prático. Não sei se existe algo parecido por aí, mas tive essa idéia durante as últimas noites: Acesso ao banco por um objeto único, com índices de array e métodos embutidos. O melhor jeito de explicar é mostrando exemplos:

PHP
$db->foo[0]; //Primeiro resultado da tabela "foo"
$db->cliente[2]->nome; //Campo "nome" do segundo resultado da tabela "cliente"
$db->foo[0]->nome = "Alexandre"; //Define o campo "nome" do primeiro resultado da tabela "foo"
unset($db->foo[0]); //Exclui primeiro resultado da tabela "foo"
$db->cliente = new clienteRecord; //Cria um novo registro na tabela cliente
$db->cliente->nome = 'Alexandre'; //Define o campo nome do novo registro

Como você pode notar, o acesso ao banco é feito como se todas as tabelas estivessem carregadas dentro de arrays. O maior desafio com certeza é fazer com que o sistema efetue as consultas e alterações sem carregar as tabelas inteiras, para não prejudicar a performance. Usarei sobrecarregamento de arrays e sobrecarregamento em objetos pra isso.

Uma das desvantagens óbvias desse sistema é na hora de buscar por algum resultado. Imagine que tenhamos que buscar todos os resultados com nome igual a “Alexandre”, seria algo assim:

PHP
$busca = array();
foreach ($db->foo as $k => $v) {
if ($v['nome'] == 'Alexandre') $busca[] = $db->foo[$k];
}

É por esse motivo que existem frameworks que implementam métodos de busca aos objetos, alguns similares a esses:

PHP
$db->foo->findByNome('Alexandre'); //Retorna array com os resultados

Se eu quiser por exemplo aumentar o salário de todos os funcionários da limpeza em 20%, faria algo assim:

PHP
$db->funcionarios->findBySetor('limpeza')->salario *= 1.2;

Essa parte dos métodos de busca e demais funcionalidades eu provavelmente não implementarei. O programador terá que fazer algo assim:

PHP
$db->funcionarios('setor = limpeza')->salario *= 1.2;

E obviamente, pode ser que eu não consiga implementar isso de maneira alguma :) Estou encontrando sérios problemas com os métodos de sobrecarga __set no PHP.

Qualquer dica que puderem me dar quanto ao formato e/ou implementação é valiosa.

A Utopia da separação do conteúdo e apresentação

Monday, July 9th, 2007

No post sobre hacks css e tabelas houve uma pequena discussão nos comentários sobre a separação de conteúdo e design. Há muita desinformação dos profissionais mais entusiastas dos padrões nesse aspecto.

Embora seja possível separar totalmente algum conteúdo de alguma apresentação específica, nem sempre é possível separar qualquer conteúdo de qualquer apresentação usando somente CSS. Em outras palavras, existem sim limitações tecnológicas no desenvolvimento com padrões, e muitas!

Nos comentários do post surgiu um desafio, após a declaração do William:

Estou para ver ainda algum caso onde não fosse possível separar completamente conteúdo de layout. Se você conhece algum exemplo me mostre, quero ver.

Preparei um desafio simples de um caso no qual é impossível separar conteúdo da apresentação e até modifiquei o desafio de acordo com as dicas do desafiado. Como não obtive resposta ainda, resolvi dar mais visibilidade ao desafio usando esse post :)

Qualquer um que solucionar o problema do desafio, não ganha um pendrive ou livro, mas ganha um post de desculpas bem envergonhado. Eu sou um desenvolvedor pobre, porém honrado :)

Meu microframework

Wednesday, July 4th, 2007

Eu tenho mesmo uma implicância com frameworks, os artigos linkados já explicam isso bem. Finalmente coloquei a mão na massa e comecei a desenvolver meu próprio framework, até o momento chamado to95lite. Algumas características do sisteminha:

  • Desenvolvido em PHP5
  • Permite usar SQLite ou MySQL (Talvez funcione com demais bancos do PDO)
  • Não usa XHTML, trabalha somente com HTML 4.01 válido e semântico
  • Contém apenas um arquivo, com no momento 18kb. Pretendo ficar abaixo dos 32kb
  • Gera arquivos de template HTML/PHP válidos, semânticos e simples de modificar
  • Cria micronavegação e formulários automaticamente para as ações: Incluir, Alterar, Visualizar, Buscar e Listar
  • Cria um arquivo CSS sem propriedade alguma, mas com as classes já declaradas para ajudar no desenvolvimento
  • Otimiza as consultas, cria índices e protege contra SQL Injection automaticamente com base nos templates modificados
  • Trabalha com URIs amigáveis, mesmo sem url rewriting por htaccess
  • Permite total tradução do sistema. Por exemplo, eu uso “incluir”, mas você pode usar “criar” ou “adicionar” para as ações se preferir, mudando apenas uma linha do sistema
  • Até o momento não possui sistema de permissões, você tem que se virar com isso
  • Ainda não tem sistema de paginação de resultados (Isso é crítico, no momento ele só retorna 10 resultados de qualquer consulta)

Fiz o teste com o framework essa semana, e com alguns poréns posso dizer que agilizou muito o desenvolvimento, basicamente, o que tive que fazer pra colocar no ar um gerenciador de processos judiciais e andamentos foi:

  • Criar as tabelas e alguns views (pra trabalhar com consultas a múltiplas tabelas) no banco de dados
  • Editar alguns templates, como eu já esperava
  • Usar redirecionamento por HTTP header para tornar alguns dos formulários enviados mais amigáveis
  • Criar um simples sistema de autenticação (15 linhas)
  • Criar o CSS inteiro, já que essa parte do sistema ainda não está pronta

Como já citei, fui forçado a usar bastante as funcionalidades do banco de dados para contornar limitações óbvias do sistema. Com um pouco de criatividade foi simples fazer buscas em várias tabelas e retornar resultados específicos com links pra cada resultado separadamente.

Em breve, coloco por aqui um tutorial e o framwork para download. Provavelmente será de como construir um blog com RSS, comentários e painel de controle autenticado, em 15 minutos (pra superar o Rails, haha).

Firefox? Que se danem as extensões, eu fico com o Opera

Monday, July 2nd, 2007

Resumo dos motivos para eu adotar o Opera ao invés do Firefox:

  • Mais rápido para abrir as páginas, sem dúvida
  • Consome menos memória, tem uma espécie de garbage collector muito bem implementado que evita páginas como o Netvibes de consumirem memória demais
  • Boa parte das extensões que o Firefox possui, são itens de fábrica do Opera
  • Trabalha melhor com downloads, sem que seja necessária qualquer modificação ou extensão
  • Tem suporte experimental aos Web Forms 2.0
  • Suportam widgets HTML e são tão bons nisso que foram os desenvolvedores do Opera que submeteram o projeto ao W3C
  • Tem suporte total ao ECMAScript, é a melhor implementação dessa linguagem que conheço. Uma pena não ser código aberto
  • Não buga os caracteres em algumas páginas como o Firefox faz. Isso me impedia de usar o Net2FTP por exemplo
  • Não sinto falta das poucas extensões que eu tinha no Firefox
  • Também pode ser portável e fica menor que o Firefox Portable nessa versão

Agora me digam, que extensões vocês admiram tanto a ponto de não migrar pro Opera e ter todas essas vantagens? Só espero que não digam que são alguma dessas.