Justificando o Rails

December 19th, 2004 § 3 comments

Ian Bicking não está particularmente impressionado com o Rails. Segundo ele, não há nada que torne o framework especial. Como um longo usuário de framework Web, eu entendo algumas das críticas dele e até concordo com algumas coisas que ele diz. Como um recém-entusiasta do Rails, eu discordo do comentário como um todo.

Como os leitores desse blog sabem, uma coisa que eu valorizo extremamente em uma linguagem ou biblioteca é a simplicidade. Mais do que qualquer outra característica, a simplicidade é o que define a utilidade e o poder de alguma ferramenta de programação para mim. E simplicidade aqui não é a mera facilidade de uso, mas uma série de coisas que tornam a ferramenta um instrumento útil a longo prazo, como eu já escrevi aqui várias vezes.

A resposta curta então, para o comentário de Bicking seria essa: Rails tem a simplicidade que nenhum outro framework que eu já usei ou pelo menos conheço possui. Como uma resposta simples e direta assim provavelmente não é tão valiosa, eu vou comentar alguns aspectos específicos do que Bicking escreveu.

Primeiro, eu concordo com o fato de linguagens dinâmicas serem superiores. Eu já programei em dezenas de linguagens para a Web, e as dinâmicas são claramente mais produtivas — mesmo PHP, com todos os seus defeitos.

Python, a linguagem que Bicking parece favorecer, é tão dinâmica como Ruby. Como fã de Smalltalk que sou, eu não favoreço a sintaxe de nenhum das duas, mas adoro as características semânticas de ambas. Eu resisti ao Ruby por um bom tempo (como o Guaracy poderia testemunhar), mas acabei me rendendo ao poder da linguagem. Ruby é construída sobre os mesmos princípios que me atraem em Smalltalk, sem sofrer das limitações dessa última que impedem meu uso (limitações não da linguagem, mas basicamente de ambiente).

E uma coisa ficou clara para mim quando eu comecei a usar Ruby e Rails: Rails teve sucesso no Ruby (e não no Python, Perl ou PHP) porque o Ruby favore o surgimento natural de tais bibliotecas coesivas e completas. Bicking quase reconhece isso, mas acredita que é mais uma coisa do momento ou de sorte. Ele diz:

[Those pieces] fit together really well in Rails, which is perhaps what it offers that Python doesn’t have. Well, I’m sure some framework out there has this, but it’s hard to say, there’s so damn many.

Quais seriam esses outros frameworks, eu não sei. Eu diria que tanto os vários frameworks para o Delphi e o ASP.NET estão na direção certa (por mais herética que essa declaração possa parecer para zelotes do código aberto), mas ainda não chegaram lá. Talvez justamente pela falta da natureza dinâmica dessas linguagens.

Os componentes que Bicking menciona acima são os três partes principais do Rails: o publicador de objetos, baseado no modelo MVC e responsável pela interface entre os objetos e o a parte de apresentação e controle da aplicação, o mapeador de modelo relacional para objetos, responsável pelo acesso orientado a objetos dos bancos que podem ser usado com o Rails, independente da natureza dos mesmos, e o sistema de templates, responsável pela parte de apresentação da aplicação.

Todas essas três partes existem ao montes em qualquer linguagem que você possa imaginar, como Bicking bem aponta. Mas a integração que o Rails provê, como eu já mencionei, eu ainda não achei em outras bibliotecas da mesma natureza.

Falando sobre o publicador de objetos, Bicking diz que eles existem aos montes em Python. O que ele não diz é que nenhum deles é tão óbvio e intuitivo como o presente no Rails, embora reconheça que os esforços para criar uma biblioteca baseada em MVC quase sempre se tornam restritivos demais ou ambiciosos demais. Este é o ponto que eu acho que ele não entendeu. O Ruby propicia esse balanço.

Mapeadores objeto-relacional existem aos montes. Qualquer programador que escreveu um sabe como é difícil fazer as escolhas certas para as complicadas interações entre esses dois modelos de manipulação de dados. Uma linguagem dinâmica facilita as coisas, mas não resolve. O SQLObject, criado pelo próprio Bicking, é excelente, encaixando-se bem na filosofia do Python, e eu concordo que que ele o equivalente do Rails são similares. Mas novamente o Rails me parece mais simples e intuitivo nessa área. O Rails possibilita em controle muito mais fino sobre o mapeamento, sem perder a simplicidade. Muito é automaticamente detectado, embora o comportamente possa ser afinado para que o programadore deseja.

Quando ao sistema de templates, eu discordo completamente da afirmação de que se parece com ASP. Dizer isso é também dizer que o Cheetah, considerado um dos melhores sistema de templates para o Python, se parece com o ASP também. O sistema do Ruby tem suas limitações, mas não fica nada a dever aos melhores do Python.

Antes de responder à última crítica de Bicking, eu quero esclarecer uma questão. Eu não estou criticando o Python. O fato de que eu estou usando Ruby agora, não significa que eu deixei de usar Python. Para mim, existem só dois estados em relação à uma linguagem: ou eu gosto, ou eu não gosto — por vezes, por questões puramente estéticas. Eu não gosto de Perl, e pronto. Perl é mais poderosa do que muitas outras linguagens, mas a filosofia por trás dela não me atrás. Entre “há mais maneiras de fazer uma coisa” e “o princípio da menor surpresa”, eu fico com esse último.

No Python, é certamente possível conseguir o que o Rails oferece. E já há esforços nesse sentido. Inclusive, a versão 2.4 da linguagem possui algumas características que vão facilitar o trabalho enormemente. Mas mesmo que o equivalente do Rails aparece para o Python, eu vou usar o do Ruby onde for possível — não porque tenha alguma coisa contra o Python ou porque comecei com o Rails primeiro. Mas sim, porque o Ruby encapsula uma filosofia que eu prefiro.

Voltando às críticas de Bicking, sua afirmação final é que, no fim das contas, o Rails não escala quando as complexidades se avolumam no projeto, tornando-se igual a todos outros frameworks existentes. Eu já desenvolvi centenas de aplicações Web e, mesmo com a experiência limitada que eu tenho com o Rails, eu posso ver que o mesmo é diferente do que usei no passado. O Rails não é uma solução mágica. Nenhuma biblioteca é. O que torna o Rails especial, como eu indiquei mais acima, é a linguagem no qual foi escrito.

Recentemente, eu tive que resolver um problema no Python: a inserção de aspectos em um objeto no momento de sua criação. Eu não queria usar um framework AOP completo, porque precisava de uma coisa simples. Na versão 2.3 do Python, não existia nada tão simples com o Ruby oferece para isso (os mixins). Os decorators do Python 2.4 surgiram justamente para resolver esse problema com uma sintaxe inteligível e compacta. Os hacks antigos (metaclasses, por exemplo) exigem um esforço considerável do programador e simplesmente não oferecem uma boa flexibilidade e capacidade de manutenção. Basta dar uma olhada no código do PEAK para perceber isso. A implementação de uma sintaxe simplificada de decorators para o Python 2.3 exigiu a captura e modificação dinâmica do contexto de criação da classe em um nível baixo demais para ser aceitável em uma linguagem de alto nível como o Python. Interessante e útil, mas em última instância problemático porque depende de detalhes que podem mudar de um versão para a outra.

Essa é a diferença fundamental do Ruby e do Python, e que se aplica também ao Rails. No Ruby, isso não é apenas possível: é óbvio também. E na hora que a aplicação precisa escalar, isso faz toda a diferença. Bicking pergunta:

Eventually you’ll need to tweak a generated form just a little does that mean you have to throw away all the automated aspects and code it by hand? (Ênfase dele.)

De forma alguma. Nessa hora, o Ruby me dá o poder de transformar apenas o comportamento que eu quero e manter o resto da funcionalidade no lugar sem preocupações.

Um exemplo simples: uma das funções do Rails permite a criação automática de listas drop-down no HTML baseada em coleções de objetos. Essa lista pode ter o primeiro item vazio para indicar um elemento opcional. Eu precisava que esse primeiro item continuasse com o valor vazio, mas tivesse um texto diferente. Mas o método era não só interno, mas privado do Rails. Solução: Ruby. A linguagem permite, como o Smalltalk, a modificação dinâmica de um objeto, mesmo de métodos que sejam privados sem precisar recorrer à herança. Eu redeclarei o método e todo o framework começou a usar a minha modificação como se ela sempre tivesse existido, sem precisar trocar nenhum classe ou fazer qualquer contorção.

Um exemplo mais complexo, baseado no exemplo citado por Bicking. Como lidar com interfaces mais complexas. O scaffolding do Rails realmente só permite a criação automática de interfaces baseadas em tabelas simples (o que já é mais do fazem que muitos frameworks). Como eu precisava de algum mais complexo, foi simples criar outro método que recebesse uma especificação do formulário que eu precisava (incluindo sub-objetos) e o contruísse de acordo com essa especificação. Para quase tudo que eu preciso, essa função resolve. Existem poucos formulários que combinam tanta lógica que exija algo específico. E antes que alguém diga que a aplicação deve ser muito simples, então, eu só mencionarei que ela é complexa o suficiente para ter uma geração dinâmica de tabelas no banco com complexos relacionamentos criados pelo usuário. E eu digo uma coisa: o Rails absorve essas tabelas dinâmicas como se elas sempre houvessem existido no modelo. (E eu comecei a desenvolver em Ruby e Rails há pouco menos que três meses.)

Requerimentos complexos de atualização e inserção? Autenticação? Junções? Existem caminhos simples no Rails para quase tudo que se precise neste aspecto. E onde o Rails não consegue chegar, já que obviamente seria impossível que ele cuidade de todas situações possível, o fato dele ter sido escrito em Ruby faz toda a diferença.

Para resumir essa justificação longa, eu corro o risco de me repetir. Como eu disse em outra entrada, simplicidade é poder. O Rails é simples. E tem atrás de si uma linguagem que preza isso ao máximo. Isso é que faz o Rails especial, eu diria.

§ 3 Responses to Justificando o Rails"

  • Como o meu trabalho não é direcionado para web, não utilizo o Rails. Portanto, não posso comentar muito sobre o Rails. Mas pelo que o Ian Bicking escreve, ele é mais um advogado do Python mesmo. Logicamente, a visão dele será mais superficial e tendenciosa.

    Copiando um pouco o Bill Clementson (que usa Blogmax), quando a gente compara duas linguagens, utilizamos o que nos é familiar.
    http://home.comcast.net/~bc19191/blog/041215.html
    Provavelmente o Ian não conhece as facilidades com que se pode fazer alterações, como ‘singleton’, alias, alias_method e outras.

    Também não conheço o SeaSide, mas o Nat Pryce dise: “SeaSide makes writing web apps startlingly simple and straightforward. In comparison, web app frameworks in the Java world, such as JSP or Struts, and even Ruby on Rails look like dinosaurs.”
    http://nat.truemesh.com/archives/000422.html
    (apesar de que existe o Borges, que é uma ‘tradução’ que o próprio Avi Bryant fez e o Wee que é uma implementação do SeaSide de forma a utilizar melhor os recursos do Ruby)

    O mapeamento O/R deve ser utilizado com cautela e em caso de necessidade ou onde traga reais benefícios. Vejo o pessoal do Delphi querendo ficar ‘na moda’ quando a utilização do modelo relacional seria muito mais eficiente e menos trabalhosa. O TaQ também tem bronca do pessoal de Java que faz isso. Talvez o melhor seria partir direto para um ODBMS

    Bem, fico por aqui.

  • Joao Pedrosa says:

    Quanto a empolgação com o Rails, eu a compartilho. Acho que a sequência de pontos altos que me levam a admirar o Rails aconteceu assim:
    1- Sequências de anuncios de lançamentos de versões do Rails. Toda semana o Rails tinha uma nova versão. hehe. Isso gerou uma curiosidade.
    2- Primeiros testes, acompanhando o tutorial e testando no webrick. Teste com o Instiki que usa o Rails. “Hmmm, isso funciona mesmo”.
    3- Vendo como o framework funciona, para criar um driver de Firebird ODBC para o Rails. “Cara, que massa isto. Tudo dinâmico. Acho que não conseguiria fazer algo assim”. Só vendo para crer. Muito do código do próprio Rails é dinâmico, isso significa que ele usa muito do poder padrão de Ruby, e por isso o criador do Rails, David H.H., é cético quanto a outras pessoas criarem um “Rails” em outras linguagens. Não que seja impossível, claro. Mas talvez mais difícil que muita gente pensa.
    4- Testes no Windows com o FastCGI. “Que massa, velocidade suficiente para servir muita gente, tranquilamente. Qual o limite disso? É possivel adaptar para mais gente? Só o tempo dirá.” FastCGI é muito massa, mas não nego que a praia disso seja ambientes unix, mas só o fato de isso existir no Windows, ajuda a dar perspectivas boas, junto com webrick e mod_ruby. :-)

    É… muita gente não entende Ruby e Rails. Por outro lado, tem gente que adoraria usar Ruby se ela fosse mais rápida, mas tudo tem seu preço. :-)

  • Ronaldo says:

    Guaracy,

    Concordo com o que você falou com sobre a familiaridade com a linguagem. É preciso usar para julgar, o que o Ian Bicking não fez.

    Sobre o SeaSide, ele realmente é um framework excelente e tem possibilidades que vão além do Rails ou de outros frameworks, mas, no fim das contas, ainda não funciona para mim por causa das suas necessidades estendidas na hora da implantação. Ainda não usei o Borges ou o Wee.

    Quanto ao mapeamento OR, eu acho que ele é melhor do que o acesso relacional direto em quase que 100% dos casos. Exceto em relatório e determinadas otimizações, facilita muito as coisas sem perder tanta performance. Um ou duas chamadas a mais ao banco, para a vasta maioria das aplicações não conta muito. Mas como toda ferramenta poderosa, deve ser realmente entendido antes de ser usado.

    João,

    Realmente o modo como o Rails foi trazido ao mundo é responsável por grande parte de seu sucesso. As estratégias foram muito boas e a ferramenta é realmente excelente.

    Sobre a performance, concordo. E como sempre, não me preocupo até ser necessário otimizar. Acho que é a melhor estratégia.

What's this?

You are currently reading Justificando o Rails at Superfície Reflexiva.

meta