Evitando o null-driven-development

Quando a programação em C estava em alta, havia uma série de alocações e liberações de memória. Depois disso, a alocação/liberação passou para C++, e a partir daí tínhamos código como o seguinte:

Person *person = new Person();
delete person;

Algumas vezes, queríamos criar um objeto mas não tínhamos todas as informações dele. Era comum usarmos o ponteiro e só atribuir ele quando tivessemos a informação:

Person *person = null;
//do something in-between
person = new Person(name);

Isso causava um efeito estranho que, eventualmente, o objeto seria “nulo”, ou “não existente”. Isso era uma novidade até o momento, já que nas linguagens mais antigas (VB, QuickBasic, Pascal, etc) ou não havia esse conceito de “nulo” ou não era comum usar.

Quando as linguagens orientadas a objeto dominaram o mercado, esse “null-pattern” acabou também entrando no mercado. Em Java (e Scala), por exemplo, qualquer operação que envolva um null lança um “Null-pointer exception” (que muitos programadores simplesmente capturam com um try-catch, mandam imprimir no console o stacktrace, e continuam o programa, que normalmente para de funcionar). Em Ruby, as coisas são mais complexas…

Ruby é a primeira linguagem que eu conheço que meio que “institucionalizou” o uso de nulos.
(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…)

O Método “Extend” e Seus Usos

Provavelmente muita gente conhece o método “extend”, usado principalmente em classes para adicionar métodos, tais como:

module Nameable
  def set_name(name)
    @name = name
  end
end

class MyClass
  extend Nameable
  set_name "Foo Bar"
end

Claro que há pessoas que fazem verdadeiras aberrações, tipo um “module” que define o callback “included” que chama um “extend”, tipo essa situação:

module Nameable
  def self.included(klass)
    klass.extend Nameable::ClassMethods
  end

module ClassMethods
    def set_name(name)
      @name = name
    end
  end
end

class MyClass
  include Nameable
  set_name "Foo Bar"
end

Mas vamos ignorar esse tipo de coisa e pensar em outras formas de usar o “extend”. Digamos que temos uma classe como a seguir:

class Authenticator
  def login(username, password)
    if User.find_by_username_and_password(username, password)
      return true
    else
      return false
    end
  end

Ok, temos uma regra para autenticar (aviso: não use isso em produção, o código prevê que os usuários tem suas senhas gravadas no banco sem criptografia nenhuma). Digamos, agora, que em um determinado cliente, esse código só não é o suficiente: o cliente quer que, antes de autenticar no banco, se autentique no sistema

Uma solução é usar monkey-patch. Nesse caso, teríamos um código em outro lugar que redefiniria a classe e adicionaria novos métodos, tipo:
(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…)

Orientado a Objetos versus Funcional

Bom, esses dias estava estudando Scala. Uma linguagem multi-paradigma, mas que parece mais “funcional” do que “imperativa”. Scala cai numa posição ainda nebulosa para a maior parte das pessoas (e acho até que para o mercado também). Afinal, imutabilidade é “programação funcional”? Scala não faz nada que impede “side-effects” no código, como Haskell por exemplo, então ela é funcional mesmo?

Como mesmo eu não tenho muitos conhecimentos em linguagens funcionais, resolvi propor um problema para mim mesmo: implementar uma árvore binária em Ruby, e depois portá-la para Scala, tentar uma abordagem imutável em Scala, e depois portar para Haskell. O código está no github, mas algumas coisas vão ser discutidas aqui.

Primeiramente, a árvore imutável é feita recriando a árvore inteira. Claro, não podemos re-criar apenas um nó e apontar, digamos, a referencia de seu pai para esse novo nó, porque o pai é imutável (assim como qualquer outro aspecto do programa).

class Node[A <% Ordered[A]](value: A = None, left: Option[Node[A]] = None, right: Option[Node[A]] = None) {
    def insertNew(newValue: A): Node[A] = value match {
        case v if(newValue < v) => insertLeft(newValue)
        case _ => insertRight(newValue)
    }

<pre><code>private def insertLeft(newValue: A) = new Node(value, newChild(left, newValue), right)
private def insertRight(newValue: A) = new Node(value, left, newChild(right, newValue))
private def newChild(child: Option[Node[A]], newValue: A) = child match {
    case Some(child) =&amp;amp;gt; Some(child insertNew newValue)
    case None =&amp;amp;gt; Some(new Node(newValue))
}
</code></pre>

}

(more…)

Testando Javascript no Rails

Continuando os estudos com Javascript e Ruby, esses dias tive um problema bem chato: existe uma gem (muito boa, por sinal) para Rails chamada “cells“, que basicamente cria uma camada, semelhante a “mini controllers” para coisas específicas em Rails (tipo “sidebar”, “carrinhos de compra”, “menus” e outras funcionalidades que são, basicamente, fragmentos de “views”, normalmente feitas com a combinação “partials+helpers” mas que ficam relativamente difíceis de testar). Junto com o Cells, foi criado o Apotomo, uma gem para criar “widgets”, e aí que está o problema: testar um widget. Claro, é possível testá-lo com integration test, mas “unit-tests”, quando envolvem Javascript+Rails, envolvem HTML Fixtures, linguagens de teste diferentes, enfim, nada produtivo.

Aí, entrou a gem Johnson. Basicamente, é um interpretador Javascript dentro de Ruby, de forma que seja possível rodar código JS dentro do Ruby (e o resultado vem como uma Ruby String, ou um Numeric, enfim). Já falei sobre isso quando estudei “The Ruby Racer” e os testes com V8 no Ruby, até me interessei pelo “env.js”, porém na época a versão que rodava com Johson estava muito ruim ainda (e infelizmente, ainda está)

Porém, o novo Env.JS (1.3) já roda no Johnson. E está muito melhor.
(more…)

Em Patópolis, Programe como os Patos

Este é um post sobre “Duck Typing”, e finalmente eu escrevi ele (estava enrrolando para fazê-lo). Acho esse post bem importante porque eu percebi, com a experiência em Ruby, que poucas pessoas sabem lidar com o dinamismo da linguagem (e aproveitá-la ao máximo).

Então, vamos falar um pouco sobre Duck Typing. O básico, a maioria já sabe:

def imprimir(objeto)
  print objeto.falar
end

Ou seja, na declaração do método eu não defino nenhuma regra do que aquele objeto pode receber; apenas chamo os métodos que eu o objeto passado como parâmetro deveria implementar, e confio que vai dar certo. Parece simples, e até um pouco inseguro, então tem gente que prefere fazer umas checagens antes (tipo usando objeto.is_a?(Pessoa) ou objeto.respond_to?(:falar)), mas eu acho que isso quebra a idéia de Duck Typing. Para mim, tudo se resume a uma palavra: Protocolo.

(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…)

Auditando Métodos em Ruby

Mais um da série “Coisas que você nunca quis fazer com Ruby, e tinha medo de perguntar”, embora o título não seja tão correto assim: bem ou mal, eu precisei fazer isso algumas vezes em um ou outro trabalho meu, mas enfim, vamos ao cenário:

Imagine que você está mexendo num código de alguém. O código está com acoplamento muito alto, e antes de refatorá-lo você precisa entendê-lo – e é aí que entra o problema. Ruby, como todos sabemos, não tem uma IDE muito boa, com um debugger muito bom, e para fazer esse processo seria legal se, por exemplo, eu pudesse rodar um comando e ele me retornasse: “Entrei no método X, Entrei no método Y, Saí do método Y”, etc.

Bom, o fato é que é bem simples de fazer isso com Ruby:

Para tal, basta “apenas” reabrir todas as classes que formos auditar, puxar todos os métodos que são implementados naquela classe, e re-escrevê-los de forma que seja informado que aquele método foi chamado. Como não há muito desafio em fazer tal coisa, apresentarei duas formas de fazê-lo.
(more…)