Clojure, and Ruby

I’m gonna make a bold claim here. As a language, Clojure is much better than Ruby. But, as a means of working together with other people, Ruby can be better, and Clojure can be a nightmare.

Here’s the problem with this debate: in Ruby it’s easier to actually bootstrap something because of the Rails framework. Clojure doesn’t have anything like that, but the code tends to get less worse as time goes by – as a functional language where everything is immutable by default, there’s less “surface” that’s touched by a piece of code. For example, suppose you have a function – in Clojure, changing that function only affects callers of that function, whereas in a mutable language, the function can mutate an object/value and now everywhere that uses that same object can be affected.

Another reason, that might be counter-intuitive is because of the real framework itself. When an application grows, you might find that you need less constraints and more freedom to do stuff that was not defined originally. Unfortunately, if you are using Rails (or any other framework), this means that you have to find ways around the framework, because it’s a kind of an “all or nothing” – it’s not that easy to basically do something outside of it and then bring that into your workflow, into your web servers and things like that (for example, I once had to integrate a SQS message queue on Rails, to listen to some message and deliver a notification via websocket. It was such a bad experience that we did a Node.JS app that did just that).
(more…)

Rails’ ActiveRecord – the bad and the ugly

I’m known to not be a big fan of ActiveRecord. No, that would be a simplification: I probably hate ActiveRecord and think it adds more problems than it solves, specially after I began to work with functional programming and saw how difficult, if not utterly impossible, is to make ActiveRecord models behave like immutable structures or separate (and maybe even predict) the I/O from the rest of the code.

The ActiveRecord pattern (not the GEM) was created to hide SQL details from the users. The Gem elevates this to extremes: you never know when a query is issue, what query is issued (unless you check the logs), and sometimes a later clause modifies the way previous clauses work. Also, to extend ActiveRecord, you need to rely on monkey-patches and other internal implementation details, and there are API changes that seem innocent but are tremendously dangerous.

Now, what I want to do in this post is to elaborate the bad and the ugly parts. I’m not gonna talk about the “good parts” because we already know: auto-discovery of fields, fast prototyping, simple CRUDs, and so on. One could argue that this “easy setup, fast prototyping” is not worth the amount of technical debt you’ll have later, but let’s focus on the bad parts instead:
(more…)

SQL Orientado a Objetos

O nome parece estranho, mas um ORM, dependendo de como ele for implementado, pode ser usado exatamente para isso.

Estou trabalhando numa lib em Scala chamada relational, na qual eu pretendo fazer um SQL inteiro virar um objeto Scala. Mais ou menos o que o Arel tenta fazer, porém de forma esquisita (meio compatível com Rails, meio compatível com álgebra relacional, e não 100% nada). Mas isso fica pra um outro momento…

No post anterior, eu falei bastante sobre SQL, e sobre todas as coisas que podemos fazer ao saber montar uma query. A idéia agora é tentar montar, de fato, uma query, mas com mais do que apenas fragmentos SQL, mas com o próprio ORM.

Vamos pensar que temos uma tabela de usuários, e uma de números de telefones. O número pertence a um usuário, um usuário tem muitos números de telefone (nada de “join-tables” e coisas mais complexas por agora). Digamos que eu queira saber números de telefone possuem o mesmo prefixo (os primeiros quatro números-vamos ignorar, por hora, os nono dígito para deixar o código mais fácil) de um determinado número.

A idéia, num primeiro momento, é fazer o código para um único número. Vamos, por simplicidade, deixar isso na classe de Telephone mesmo:

class User < ActiveRecord::Base
  has_many :telephones
end

class Telephone < ActiveRecord::Base
  belongs_to :user
  
  def self.same_prefix_of(telephone)
    where('SUBSTR(telephones.number, 0, 5) = ?', telephone.number[0...4])
  end
end

#Para usar:
Telephone.same_prefix_of(Telephone.first)

Por hora, tudo bem. Um código simples, porém é agora que a coisa começa a ficar divertida: generalização
(more…)

Resourceful Web

Todos sabem que, com o tempo, os frameworks web evoluem. Porém, o que poucas pessoas percebem é que além das mudanças nas APIs e na estrutura dos programas feitos com o framework, há uma mudança também nas idéias dos desenvolvedores e até mesmo nas metáforas que o sistema usou para definir-se. E o Rails não é exceção.

Por exemplo, no Ruby on Rails versão 1.x, a idéia do framework era a construção de aplicações web. Para tal, a idéia era que a aplicação fosse simples e divertida de desenvolver. Além disso, havia a idéia de web-services, XML-RPC e SOAP que nunca pegaram direito no mundo Rails (mas que estavam presentes na versão 1.x). Depois, na versão 2.x, surgiu o conceito de RESTful (em contraponto aos web-services do Rails 1) e, junto com ele, o conceito de “resource” ou “recurso”. Já no Rails 3, surgiu a idéia de separar o Javascript do HTML usando o conceito de Unobtrusive Javascript (Javascript não-intrusivo), e junto com essa idéia, veio a substituição do prototype pelo jQuery (que torna certas operações envolvendo AJAX mais fáceis). Junto também com a substituição por jQuery, o scaffold passou a fazer os controllers responderem por HTML e JSON, ao invés de HTML e XML como no rails 2.x.

E é essa a mudança mais importante.

Vamos começar pensando: qual seria o motivo de renderizar um JSON? A resposta é simples: JSON é mais fácil de ser entendido pelo browser, por Javascript, e por aplicativos de terceiros tais como em iOS ou Android. Antes, responder por XML não tinha aplicação real nenhuma nos próprios aplicativos Rails, e ficavam apenas como forma de comunicação com sistemas de terceiros (o velho “big design up front“) que nem sempre ocorriam. E hoje, renderizar JSON está muito pouco utilizado mesmo no mundo Rails, e há um motivo para isso:

Não sabemos o que é um “resource”.
(more…)

Testes de Controller – a Saga

Semana passada comecei finalmente um projeto do zero usando Rails 3.1. A experiência foi novidade para mim, que por causa de uma série de legados (e também por questão de performance) estava preso no Rails 2.3, e não tive a oportunidade de ver como os testes funcionam no Rails 3.

Mas antes de chegar no assunto, vamos rever que o Rails não é puramente MVC. O “Controller” do Rails agrega coisas que deveriam ser feitas na view (basicamente, buscar o objeto para ser exibido). Para mais detalhes, ver meu post anterior.

Por esse motivo, e unicamente por este motivo, eu não acredito ser possível fazer teste unitários de controllers.

Um teste unitário deve, em teoria, testar um pedaço do sistema, isoladamente de outras partes. Como fazer um teste unitário de algo que é, essencialmente, um “glue code”, ou seja, um código que une regras de negócio (Models) e interfaces (Views)?

Antes do Rails 3, eu usava uma abordagem mais “integrada” para esses specs. No controller, eu usava a palavra-chave do rspec-rails “integrate_views”, e testava o par “controller-view”. Os specs ficavam mais ou menos assim:

describe PeopleController do
  integrate_views

it 'should show people on "index"' do
    sessions[:user_id] = Factory(:user).id
    Factory :person, :name => "Foo Bar Baz"
    get :index
    response.should be_success
    response.body.should include("Foo Bar Baz")
  end

it 'should render "new" view if validation failed" do
    sessions[:user_id] = Factory(:user).id
    post :create, :person => { }
    response.should render_template("new")
  end
end

Claramente, isso não é um teste unitário, mas há um grande ganho nessa abordagem: se eu resolver mudar a variável “@users” para “@records”, e atualizar a view, não preciso mexer em nenhum spec. Na prática mesmo, eu não preciso mexer em nenhum SPEC se eu mudar o layout, adicionar mais informações na view, buscar mais registros no controller e atualizá-los na view, enfim, em qualquer momento eu sei, exatamente, se o teste está falhando ou passando, sem as fragilidades que mocks podem oferecer.
(more…)

Model View Controller

Ultimamente, Rails tem se popularizado, e com ele o famoso (e já antigo) MVC. Porém, como todas as coisas, a prática acabou sobrepondo a teoria, então achei que seria interessante falar um pouco sobre MVC, já que parece-me que algumas confusões começaram a acontecer. Esse post é imensamente baseado nesse post do Martin Fowler sobre arquiteturas GUI, então seria interessante ler ele também.

Enfim, vamos lá: no Rails, quando fazemos um “scaffold”, é criada uma combinação de coisas para nós: uma “migration”, que cria uma tabela no banco. Um “model”, que basicamente é o mapeamento dessa tabela para um objeto. Um “controller”, que faz a busca do registro certo e repassa para a renderização da tela. Por exemplo, a ação “edit”:

  def edit
    @foo = Foo.find(params[:id])
    render :action => 'edit' #Isso é redundante, mas deixa explícito um aspecto importante.
  end

Além disso, há uma série de boas-práticas, tais como não concentrar código de regra de negócio no controller, não colocar lógica nas views, enfim. Porém, essas “regra gerais” pecam em um ponto:

Rails não é 100% MVC…
(more…)

Regras de Negócio e Rails

Bom, esse post é resultado de uma conversa que tivemos no Grupo de Usuários de Ruby de SP. Mas, antes de entrar no que interessa, vamos divagar um pouco sobre “Model” e “Rails”.

Muitos programadores Rails sabem a regra “Controllers magros, Models gordos”. É interessante também saber um pouco sobre o porque dessa regra, mas antes disso, vamos discorrer sobre o que é o “Model” de Rails, comparando com o “Model” da maior parte dos frameworks Java (lembrando que eu não sou programador Java, se eu falar qualquer besteira, me corrijam).

Pegando por exemplo o Hibernate, normalmente há uma classe que mapeia um objeto para uma tabela, e outra classe que faz as buscas (chamada normalmente de Facade). Então, teríamos um diagrama como: JDBC -> Model -> Facade. Já no caso do Rails, o mapeador ActiveRecord já abstrai a parte de “ter que mapear um objeto para uma tabela”, e também já nos oferece formas de buscar esses registros. Resultado, que o “Model” do Rails é meio que uma junção de “Model” e “Facade” do Java, e isso sozinho. Parece então óbvio que regras de negócio vão para ele, não é? Senão, qual o uso de uma classe vazia?

Bom, minha abordagem não é bem essa. E para isso, eu uso o princípio das CRC Cards, da metodologia XP.
(more…)

Otimizando com Javascript

Inicialmente, o nome desse post era pra ser: “otimizar ou escalar?”, mas acabei optando por este outro nome. Afinal, a postagem é sobre como foi otimizado, então…

Há algum tempo, aqui em meu trabalho, sofríamos com um sistema meio problemático: o sistema em questão é um sistema montado para que alunos possam escolher disciplinas, e é feito em duas fases. Nosso problema específico era com a segunda fase: um aluno só pode escolher uma disciplina desde que ela possua vagas, e como há certas disciplinas que muitas pessoas querem, isso vira uma corrida contra o tempo: praticamente metade da universidade acessando o sistema ao mesmo tempo, para conseguir sua vaga, e o sistema demorando muito tempo para completar cada requisição, enfileirando requisições, e um tempo absurdo para atender cada uma…

Enfim, foi jogado mais poder de processamento, mas para cada um processador que acrescentávamos, entravam mais quinheitos alunos, e cerca de cem disciplinas. Claramente, não haveria load-balancer que aguentasse, nem máquina que pudesse aceitar. Estudamos uma base não-relacional, diversas soluções, até chegar em uma: processar a página no cliente.
(more…)

ArelOperators e Buscas sem SQL

Continuando o trabalho em cima da biblioteca ArelOperators, há algumas novidades.

Para o pessoal que foi no encontro do Guru-SP, apresentei um pouco do trabalho. A idéia, conforme o post anterior sobre o assunto, é tornar o Arel mais transparente na hora de formar queries no ActiveRecord, aproveitando os recursos de Operator Overloading do Ruby.

A idéia é bem simples, na verdade, mas vem de uma dificuldade que eu acredito que muitos desenvolvedores têm: quando estamos escrevendo um código em qualquer linguagem, seria bom se pudéssemos apenas usar aquela linguagem para resolver nossos problemas. Não é conveniente usar duas, três linguagens no mesmo código-fonte (exceto, talvez, para o pessoal que usa Java, que tem que se entender com XML… ok, parei de zuar Java, juro!), e nem é recomendável de acordo com o fantástico livro “Clean Code”, do Robert Martin.

Então, por que SQL? Com uma linguagem expressiva como Ruby, e uma biblioteca fantástica como o Arel, não há mais motivos pra escrevermos “fragmentos de SQL” ou mesmo ficar fazendo “joins” e buscas estranhas manualmente. E isso trás algumas mudanças na cultura de buscas em banco de dados.
(more…)

Arel e Operator Overload

Finalmente, o Rails 3 foi lançado, e junto com ele vieram diversas funcionalidades legais: maior suporte para frameworks Javascript, mais rápido, mais agnóstico, etc etc… mas na minha opinião, a maior vantagem está no ActiveRecord 3.0

O ActiveRecord ganhou uma dependência chamada Arel, uma biblioteca de álgebra relacional. Muitos blogs já falaram sobre o assunto, então não vou me extender, vou direto ao ponto: Ruby é uma linguagem orientada a objeto, e ela é BOA no que faz. SQL é uma linguagem para fazer buscas, e devo dizer, ela também é BOA no que faz. Ruby entende objetos, SQL entende tabelas, e, bom, misturar os dois deveria ser muito mais transparente do que é. Por exemplo, o código a seguir:

maiores = Pessoa.maiores_de_idade
homens = Pessoa.homens
return maiores + homens

(more…)