ArthurGeek.net

Rails, Mac... e Rock'n Roll!

Pôr do sol em São Paulo

Códigos mais claros usando Ruby!

22 de Maio de 2007 às 14:34 · 5 comentários

Acabei de ler este artigo no blog Softies on Rails, e resolvi traduzí-lo. Sabe quando você conhece determinada função, e mesmo sabendo que ela é útil, nunca usa? É preciso ler um artigo pra "cair em si", não é?. Então, este artigo é um deles. Pelo menos foi pra mim.

Segue tradução livre:

Uma das razões para que eu ame Ruby é que o meu código normalmente pode ser lido como se fosse Inglês. Quando meu código se torna legível como uma sentença em Inglês, eu acredito que irei codificar exatamnte aquilo que eu quero atingir. Código é mais fácil de entender e manter quando a intenção original do código é evidente. Eu acho que é por isso que Java e C# são tão atrativas se comparadas com C++. E porquê C++ é tão mais legal que C.

Ruby é uma grande lunguagem, assim como Chicago é uma grande cidade. Porém hoje, eu gostaria de nos aventurarmos por uma rua transversal, pegar uma estrada menos usado por iniciantes em Ruby. Nós iremos aprender como usar modificadores de forma de algumas palavras reservadas Ruby muito bem conhecidas para melhorar a clareza do código.

Diga xiiis

Digamos que nós iremos escrever um código para operar uma câmera digital. Você tem métodos como capture_image, por exemplo, que captura uma imagem do sensor e gera um arquivo de imagem no cartão de memória (e se estivermos com sorte, emite um som de "click" para imitar uma câmera analógica). Vamos ver como você poderia escrever o código para quando o usuário pressionar o botão de disparar.

def botao_de_disparo_clicado
  if @camera.desligada? || @camera.cartao_de_memoria_cheio?
    return
  end
  capture_image
end

Então, se a câmera estiver desligada ou se estivermos sem memória, não fazemos nada. Se tudo estiver bem, nós tiramos a foto. Este era o meu estilo quando eu comecei com Ruby, e se este código com o que você faz também, então você está pronto para algo novo e recompensante.

A chave é saber que as palavras reservadas como return, while, if, unless e until podem ser usadas como modificadores. Isto quer dizer que você coloca a parte condicional depois da palavra reservada. Parece besta, e em algumas vezes realmente é. Porém, algumas vezes pode ser recompensador.

O código que escrevemos estava tentando verificar alguns requerimentos. Para poder tirar a foto, a câmera não pode estar desligada e o cartão de memória não pode estar cheio. Usando modificadores de forma para return, você pode reescrever o código acima assim:

def botao_de_disparo_clicado
  return if @camera.desligada? || @camera.cartao_de_memoria_cheio?
  capture_image
end

A primeira linha diz, retorne imediatamente se a câmera estiver desligada ou o cartão de memória estiver cheio. Se chegarmos até a segunda linha, nós podemos prosseguir e capturar a imagem. Leia o código acima em voz alta. Parece melhor, não?

Mas espere, nós podemos ir um passo à frente. Por exemplo, você poderia preferir isto:

def botao_de_disparo_clicado
  capture_image unless @camera.desligada? || @camera.cartao_de_memoria_cheio?
end

Agora, leia alto novamente: "Capture a imagem a não ser que a câmera esteja desligada ou o cartão de memória esteja cheio.". Isto expressa a nossa intenção de uma maneira um pouco diferente. Quando lemos alto, a primeira coisa que ouvimos é "capture a imagem". Eu acho mais vantajoso de ouvir isto primeiro, porquê é o que acontece em 90% dos casos em que o disparador é clicado. Escrevendo códigos desta maneira, nós emfatizamos o comportamento esperado. Nós usamos a cláusula unless para guardar o comportamento com nossas regras de negócio. O código é mais transparente, fazendo com que os requerimentos sejam mais fáceis de visualizar. Este código é mais fácil de entender e manter.

Porém, vamos voltar ao código original por um minute. Não existe maneiro certa ou errado de fazer isto, e pode ser que você não tenha gostado do meu original. Finalmente, ele tem este return desajeitado flutuando no espaço.Trocando o operador lógico de lugar, o código original poderia ficar assim:

def botao_de_disparo_clicado
  if @camera.ligada? && @camera.memoria_disponivel?
    capture_image
  end
end

Dessa maneira já se lê melhor. Porém, nós ainda temos esse sentimento if-then. Parece mais como código, e menos como Inglês. Que tal isso?

def botao_de_disparo_clicado
  capture_image if @camera.ligada? && @camera.memoria_disponivel?
end

De qualquer jeito, agora é com você. Eu escrevi código Ruby da "maneira antiga" por muito tempo, e foi somente nos últimos seis meses que eu mudei para os modificadores de formas. Somente use a forma que parece mais natural à você.

Como se fosse 1999

Agora suponha que você tem um novo requerimento que diz que a câmera deve ter a habilidade de tirar fotos sem-parar em uma maneira estroboscópica até todos os bytes da memória serem usados. (Você pede ao cliente, porquê, mas porquê alguém iria querer esta habilidade, porém é um "must-have", uma habilidade que a câmera "absolutamente não pode deixar de ter". Então, você prossegue.)

Na verdade, este parece ser um métod fácil de escrever:

def fique_louca
  while (@camera.memoria_disponivel?)
    capture_image
  end
end

Novamente - você vem escrevendo código assim por um bom tempo, e especialmente se você vem do VB.Net ou C# ou Java, este código provavelmente parece perfeitamente legível à você. Seu problemo é que está na caverna por tanto tempo, que você acredita que a tocha na parede te dá luz suficiente. E se você pudesse escapar para o mundo e ver o sol? Olhe para:

def fique_louca
    capture_image until @camera.cartao_de_memoria_cheio?
end

"Capture Imagem até o cartão de memória esteja cheio." Ou se você preferir,

def fique_louca
  capture_image while @camera.memoria_disponivel?
end

"Capture imagem enqunato a memória estiver disponível.".

Apenas faça isto

Os modificadores de formas não são apenas sutilezas ou reconsiderações da linguagem. Eles estão lá por algum motivo. Tente usá-los por um tempo e veja se isto não melhora o seu estilo. Use-os onde e quando parecer aprepriado à você. Deixe a intenção do seu código clara e óbvia.

Tags:

5 comentários até agora ↓

  • 1 Cristiano // 22 de Maio de 2007 às 14:43

    Legal Arthur, está de parabéns! Quando você pode instalar o beryl no seu Ubuntu para eu ver os efeitos pois em casa não consigo... um abraço.

  • 2 Nando Vieira // 04 de Junho de 2007 às 20:05

    Arthur, eu fiz um post sobre isso também: http://simplesideias.com.br/o-modo-ruby-de-fazer/

    Aqui também dá para achar bastante coisa legal: http://www.google.com.br/search?q=ruby-idioms

    Parabéns pelo novo blog! ;)

  • 3 Walter Cruz // 07 de Junho de 2007 às 00:24

    Muito interessante o jeito ruby de fazer :) Mas confesso que ainda sou muito ifelse :)

  • 4 Thomaz // 14 de Junho de 2007 às 05:05

    Li o artigo original em inglês, é realmente muito bom. E parabéns pela iniciativa de traduzí-lo!

  • 5 Marcio Luis // 20 de Junho de 2007 às 12:31

    Legal mesmo Arthur, o bom que posso ir direto na fonte, como trabalho com vc… hahahaha… Parabéns.

Deixe um comentário