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

Bytecodes, e JIT

Resolvi escrever este post por muitos motivos, mas o principal deles é porque vi muitos amigos e colegas meus sem saber, direito, o que é um bytecode. Muitos acham que apenas linguagens como Python (com seus arquivos .pyc) e Java (com seus arquivos .class) possuem bytecodes, justamente porque ao “compilar” o programa, um novo arquivo é criado.

Nada poderia estar tão longe da verdade.

Bytecode é um conjunto de instruções, em forma binária ou seja, em uma forma não legível por humanos, que instrui uma máquina virtual a fazer determinadas ações. Bytecode não é apenas um arquivo, ou um código intermediário entre o executável nativo e a linguagem, e na maioria das vezes nem sequer é um código otimizado, com algumas raras exceções (scala 2.8, por exemplo, pode otimizar “tail call” em recursões). É importante entender essa parte, porque nem sempre um bytecode é gravado em um arquivo, e em algumas vezes sequer é um formato simples.
(more…)

Update: o que estou estudando?

Como faz tempo que não posto nada no blog (falta tempo), resolvi fazer este post meio que para iluminar um pouco o que tenho estudado ultimamente.

Comecei a aprender Scala. Na verdade, peguei esse tempo para estudar linguagens interessantes, que há tempos quero estudar como Scala, Haskell e Lisp. Criei um repositório de testes para brincar com essas linguagens no meu github: https://github.com/mauricioszabo/learning. Futuramente, farei posts sobre Scala também, que é uma linguagem interessante para substituir Java.

Comecei também a estudar desenvolvimento para Android. Instalei o emulador, fiz uns “hello, worlds” com Scala, Java e JRuby (Ruboto), o suficiente pra descobrir que rodar algo em Ruboto é inviável de tão lento…
(more…)

Como eu Entendo BDD

Test Driven Development, ou Behaviour Driven Development… duas “buzzwords” que, só de serem pronunciadas, trazem milhares de sentimentos. Porém, isso não mostra uma cruel realidade:

Poucas pessoas concordam com o que é, de fato, “teste de software”.

Em uma apresentação que fui, no AgileBrazil, com cerca de 150 pessoas na platéia, o apresentador lançou a pergunta: “o que é teste de software para você?”. O experimento era escrever em um papel sua resposta, e trocar com a pessoa do lado. Estranhamente, apenas 5 pessoas, na platéia toda, receberam um papel com uma explicação que batia com a sua.

Então, acho que seria interessante citar o que eu entendo por Teste de Software, e porque eu considero que pratico “Behaviour Driven Development”.
(more…)

Métodos privados semelhantes a Java/C++ em Ruby

Fazia um tempo que eu não postava uma das bizarrices em Ruby, então vamos lá: esses dias, no grupo de usuários de Ruby, surgiu uma discussão muito boa sobre métodos privados e alto acoplamento. A idéia é mais ou menos assim: em Java (ou C++), ao definir um método público que chama um método privado, se você reimplementar aquele método privado, os métodos públicos herdados não são afetados. Um exemplo vale mais que mil palavras, então:

#include <stdio.h>

class Example {
    public:
    void imprimir() {
        hello();
    }

    private:
    void hello() {
        printf("Hello, world!\n");
    }
};

class Ex2: public Example {
    private:
    void hello() {
        printf("Hello, from Ex2\n");
    }
};

int main(void) {
    Ex2 e;
    e.imprimir(); //Essa linha imprime "Hello, world!"
}

Já no código Ruby equivalente:

class Example 
  def imprimir()
    hello
  end

  private
  def hello
    puts "Hello, world!"
  end
end

class Ex2 < Example 
  private
  def hello
    puts "Hello, from Ex2"
  end
end

Ex2.new.imprimir #Imprime "Hello, from Ex2"

Ou seja, reimplementar métodos privados numa subclasse pode quebrar métodos da superclasse. Embora eu considere isso uma peculiaridade da linguagem e não como um problema de acoplamento, implementação falha, ou qualquer coisa (e até, mais pra frente, pretendo escrever um post sobre o assunto de diferenças entre linguagens de programação além da sintaxe), a discussão inteira me deu uma idéia: como implementar esse comportamento em Ruby?
(more…)

Closures, Functions e Programação Funcional em Javascript

Estes dias, tive que fazer um código que achei que seria muito complicado, e que deveria rodar num browser. A idéia é que, dependendo do que foi digitado em uma determinada caixa de texto, um pedaço de uma página deveria mudar. Até aí, tudo bem, o problema é que o pedaço que deveria mudar deveria agrupar informações de outras caixas de texto, e outras regras confusas. Achei uma solução muito simples e prática, e gostaria de dividí-la. Mas antes, vamos simplificar o escopo:

Imagine que há uma página, no qual há um botão “adicionar”. Ao clicar nele, ele adiciona um “select” (sexo) e uma caixa de texto com observações ou qualquer outra coisa. Podem ser adicionados tantos elementos como se achar necessário. Para cada elemento alterado, deve ser exibido um sumário na tela de baixo (observações), digamos, concatenando o sexo e as observações. A parte difícil é: quando qualquer elemento for mudado, APENAS o sumário relativo àquele conjunto de elementos (sexo e observação) deve ser alterado, e também, quando eu estiver editando as observações (ou o sexo), o sumário deve ficar em negrito. Para simplificar (e rodar em vários browser) usarei a biblioteca Javascript chamada Prototype (não usarei o JQuery porque seria jogar uma bomba numa mosca), e a idéia é escrever apenas o código relativo às edições (porque é isso que pega). Portanto, para quem quiser, basta pegar o gist do Github http://gist.github.com/658668 para ter um esqueleto do programa (basta abrir o .html em qualquer browser).
(more…)

Monkey-Patch seguro, em Javascript

Continuando os estudos com Javascript, diversas coisas interessantes, que pareciam acessíveis apenas aos programadores de Ruby, Perl e outras linguagens mais flexíveis podem ser feitas também na linguagem. O problema é que, normalmente, é difícil de usar isso em bibliotecas que já existem, principalmente porque a maioria dos códigos em Javascript ou não seguem boas-práticas ou simplesmente são escritos de forma diferente do que vou apresentar aqui, porém vale pela dica. Um exemplo bem simples, pensando na seguinte API:

objeto = {
  valor: 10,
  incrementar: function(v) { 
    if(!v) v = 1;
    valor += v;
  },
  raizQuadrada: function() {
    Math.sqrt(incrementar(4));
  }
}

Para implementá-la, em Javascript, há várias formas. Simulando o comportamento que eu fiz no post passado, é possível usar o seguinte formato:
(more…)

Estudos com Javascript

Recentemente, comprei o livro Javascript – the Good Parts, do Douglas Crockford. A principal motivação, não vou negar, foi o node.js (e o fato que muitas pessoas na net têm falado de Javascript como uma das mais “novas” maravilhas. Mas isso fica pra outro post). O livro, embora tenha uma série de problemas (e o principal é a ausência de exemplos claros, além de dar pouca ênfase ao “Javascript way”, na minha opinião) é muito bom e traz algumas definições no mínimo diferentes sobre Javascript.

Basicamente, o que é Javascript? Javascript é orientado a objeto? Javascript é funcional? Javascript suporta classes, suporta….?

Para começar, Javascript é uma linguagem de programação com sintaxe semelhante a C++, dinâmica, com tipagem absurdamente fraca, pseudo-orientada a objetos, orientada a protótipos e funcional. Wow… um de cada vez.
(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…)