Últimos Artigos:

Rss Feeds

Rails Way #7: Geradores de Código

Por Carlos Brando em 07 de Abril de 2009 | 6 comentários

2084287794_ecbee303db

O Ruby on Rails possui algumas dezenas de geradores de código que visam automatizar tarefas repetitivas, economizando o tempo de desenvolvimento e evitando que o programador tenha que se repetir. Geradores de código tem tudo a ver com a filosofia “Don’t Repeat Yourself”.

Aplicativos que geram código

Se expandirmos nossos horizontes para outras linguagens de programação menos dinâmicas, talvez geradores de código possam ser muito úteis na criação de arquivos XML de configuração, justificando de maneira óbvia o seu custo. Ao usar ferramentas como o Microsoft Visual Studio eu simplesmente informava ao editor que desejava criar uma aplicativo MFC (Microsoft Foundation Classes) e ele gerava para mim um esqueleto com mais de 2000 linhas de código, uma economia de tempo incalculável.

Algumas pessoas são totalmente contra este tipo de gerador de código porque na maioria dos casos o programador que o utiliza não entende exatamente o que o código gerado está fazendo. Embora isto seja uma realidade, isso não deve ser uma justificativa para evitar ferramentas como essa, já que na maior parte do tempo o problema está no programador e não na ferramenta. No exemplo que dei acima, embora eu nunca tenha parado para analisar cuidadosamente o que cada uma das 2000 linhas de código gerados pelo Visual Studio faça, eu entendo no contexto o porque delas, e para mim isto sempre foi o suficiente para tocar um projeto à partir deste esqueleto.

No Rails também encontramos alguns geradores deste tipo na forma de scripts (./script/generate scaffold, por exemplo). Os scripts geradores de código do Rails nos ajudam a manter as convenções propostas pelo framework com mais facilidade, e normalmente incluem apenas algumas poucas linhas de código em cada arquivo gerado.

Raramente você achará útil criar um script ou aplicativo gerador de código para um projeto Rails. Mas ao criar um plugin ou mesmo o seu próprio framework em Ruby, talvez seja prático investir na criação deste tipo de gerador. Mas não se engane, construir um gerador de código deste tipo é uma tarefa que consome tempo e um grande esforço. Além do tempo gasto na codificação do gerador, também deve-se levar em consideração o esforço necessário para manter o projeto (atualizações, correções de bugs e inclusão de novas funcionalidades) e para treinar a sua equipe (e re-treinar após modificações).

A escolha do seu editor preferido também depende muito da capacidade que ele possui de gerar código. O TextMate, por exemplo, durante muito tempo foi (no meu caso ainda é) considerado o melhor editor para se trabalhar com código Ruby, e isto se deu graças aos seus famosos Bundles, que não são mais do que scripts geradores de código.

Muitos editores também permitem que você crie seus próprios “bundles”. Na maior parte do tempo é mais fácil e barato criar um script utilizando as ferramentas que seu editor lhe fornece do que criar um aplicativo do zero afim de automatizar a criação de códigos mais simples.

Metaprogramação

Usamos metaprogramação para criar softwares que tenham a capacidade de escrever código por si mesmo. Um bom exemplo disso é o ActiveRecord do Rails, que cria em tempo de execução todo o código necessário para a manipulação de informações de um banco de dados. Ao adicionar uma nova coluna no banco de dados, não precisamos alterar nenhuma linha no código do modelo, o ActiveRecord usando metaprogramação consegue identificar a nova coluna e automaticamente criará todos os métodos e atributos necessários para permitir o acesso a esta nova coluna.

Linguagens dinâmicas como o Ruby favorecem muito o uso de metaprogramação. Programadores mais avançados fazem muito uso destes recursos para diminuir repetições em seus códigos.

A ferramenta mais comum de metaprogramação é um compilador, já que ele permite que você escreva pequenos programas em uma linguagem de alto nível afim de gerar programas em linguagem de máquina. Uma brincadeira comum que envolve o exercício de metaprogramação é montar um quine, que é um programa que deve produzir uma única saída que é o seu próprio código fonte. Veja um exemplo em Javascript:

unescape(q="unescape(q=%22*%22).replace('*',q)").replace('*',q)

Execute o código acima e você terá como saída um texto com exatamente o mesmo código gerador. Tente fazer o mesmo em Ruby, é um bom exercício!

Helpers

O diretório helpers não foi adicionado ao Rails à toa, ele está lá para ser utilizado. Helpers são fáceis de criar e podem ajudar a diminuir uma quantidade razoável de repetições em suas views. Quando criados utilizando-se de recursos de metaprogramação podem fazer uma grande diferença.

Linguagens de marcação como o Haml, servem de grande incentivo para estimular a criação de helpers em projetos Rails.

Finalizando

Geradores de código são ferramentas essenciais no dia-a-dia dos programadores e são extremamente importantes para aumentar nossa produtividade e evitar que tenhamos de escrever códigos desnecessários.

Faça uso dos geradores que você tem a disposição, e também crie seus próprios geradores quando forem realmente necessários. Mas mantenha-se longe de geradores que criem código que você não sabe para que serve ou que não entende.

Só os imaturos não testam

Por Carlos Brando em 06 de Abril de 2009 | 7 comentários

No sábado passado aconteceu em São Paulo o primeiro evento organizado pelo Guru-SP, o Ruby + Rails no mundo Real 2009. Eu e toda a equipe do Ruby Inside Brasil estivemos presentes no evento. Você pode conferir uma cobertura completa das palestras no site.

Eu tive o privilégio de participar do evento como palestrante. Minha palestra foi voltada para o público iniciante/intermediário, e falei sobre como os testes são importantes para a evolução profissional de um desenvolvedor. Como não consegui entregar os slides antes do evento, eles não foram impressos nas apostilas distribuídas, então segue abaixo via SlideShare a minha apresentação. Logo deve sair os vídeos do evento!

Contrate gerentes de si mesmo

Por Carlos Brando em 02 de Abril de 2009 | 2 comentários

Quando você estiver contratando, procure por pessoas que gerenciem a si mesmas.

O que isto significa? Um gerente de si mesmo é alguém que tem as suas próprias metas e às executa. Eles não precisam ser direcionados o tempo todo. Eles não precisam de check-ins diários. Eles fazem o que um gerente faria – definem o tom, atribuem tarefas, determinam o que precisa ser feito, etc – mas fazem isto por si e para si.

Essas pessoas te livram do trabalho de supervisão. Elas definem sua própria direção. Quando você os deixá sozinho, eles o surpreendem com o quanto fizeram. Elas não precisam de muitas instruções ou supervisão.

Como você pode detectar essas pessoas? Olhe para a sua história. Eram auto-suficientes em empregos anteriores? Já definiram seu papel antes? Já iniciaram seu próprio site ou empresa antes? Ou inventaram sua própria maneira de fazer as coisas? Encontre alguém com iniciativa e com um espírito empreendedor florescendo. E então, alimente este espirito.

Você quer alguém que é capaz de construir algo à partir do nada. Quando você encontrar essas pessoas, elas liberarão o resto de sua equipe para trabalhar mais e gerenciar menos.


Este texto é uma tradução de um artigo do blog Signal vs. Noise.

Promoções no Ruby Inside

Por Carlos Brando em 01 de Abril de 2009 | deixe um comentário

logo-br

Hoje a equipe do Ruby Inside Brasil se reuniu para tomar algumas decisões administrativas e para o bem da comunidade rubista brasileira decidimos começar a distribuir alguns prêmios para nossos leitores. O Ruby Inside Brasil não tem a pretensão de obter algum tipo de lucro, mas algumas empresas tem nos procurado afim de veicular algum tipo de propaganda nas páginas do site, assim decidimos que repassaremos todos os recursos obtidos para nossos leitores.

Para você ter uma ideia, neste momento estamos sorteando entre nossos leitores uma vaga nos dois cursos mão na massa da Tempo Real, um de Ruby e outro e Rails. Cada curso representa um investimento de R$ 249,00, mas para você pode sair de graça e participar do sorteio é ridiculamente fácil.

Agora, se sua empresa está promovendo um curso, sua editora acabou de publicar um livro sobre Ruby/Rails ou mesmo se você está lançando algum projeto e gostaria de ver isto noticiado no Ruby Inside Brasil, envie uma mensagem através da nossa página de contato e teremos o maior prazer em ajudá-lo!

A importância da definição das expectativas

Por Carlos Brando em 27 de Março de 2009 | 1 comentário

Esta semana estou trocando o telhado da minha casa. Eu pesquisei, fiz cotações, escolhi uma empresa e eles já estão trabalhando nisso agora.

Eles estão trabalhando nisto há dois dias até agora, mas já fui surpreendido por duas vezes. Isto me fez lembrar de como é importante definir as expectativas de seus clientes.

Dia um

Eles arrancaram o telhado antigo. Você não pode ver o céu, são apenas telhas velhas, o teto ainda está lá. Eu não tinha ideia da bagunça que isto iria fazer no piso superior da minha casa. Lascas de pintura, poeira do telhado caindo através de algumas fissuras e a remoção das claraboias. Acho que eu deveria ter previsto que isto aconteceria, mas eu nunca tinha feito isto antes.

Teria sido ótimo se a empresa dissesse…

“Ei, quando arrancarmos o telhado antigo pode ser que caia alguma poeira preta e lascas da pintura no piso superior. Talvez você queira cobrir seus móveis ou outras coisas de valor para o caso de isto acontecer.”

Dia dois

Estão queimando alguma coisa lá fora. Eu não sabia que teriam de queimar algo. Eu estava trabalhando em casa e imaginando como seria o cheiro de ácido queimado e de fumaça pela casa. Agora eu sei como é.

Teria sido ótimo se eles dissessem…

“Ei, hoje vamos trabalhar com tochas e materiais tóxicos. Um pouco de fumaça e gases podem entrar na casa durante este processo. Talvez seja melhor você sair de casa, enquanto estivermos fazendo isso.”

Dia três

Não tenho a menor ideia do que vem a seguir. O que acontecerá amanhã? Eles não dizem nada, apenas fazem e então você descobre.

Seria muito bom se no final de cada dia eles dissessem…

“Ei, até agora terminamos AB e C. Amanhã vamos fazer D. Assim você já saberia o que esperar.”

Definir as expectativas é a chave

Eu confio no trabalho deles, mas a experiência tem sido amarga pela falta de expectativas. Bastaria me dar uma ideia do que iria acontecer hoje e amanhã e nossa experiência seria significativamente melhor.

3203863565_04d6cae88e

Eu confio no trabalho deles, mas a experiência tem sido amarga pela falta de expectativas


Este texto é uma tradução de um artigo escrito por Jason Fried para o blog Signal vs. Noise.

Remarkable 2.3 is out!

Por Carlos Brando em 18 de Março de 2009 | 2 comentários

Remarkable 2.2.x series was made of frequent releases with deprecation warnings to consolidate the API. Until we get into 2.3, we improved support for ActiveRecord validations, fixed some bugs and made some changes, so we are safe and clear to work on new features and new matchers.

We also run our specs suite in Rails 2.3.x and Rspec 1.2.0 to assure that everything is working as supposed, and they are. :)

Keep on checking, we will have very good news, very soon. So get Remarkable on Github, appear in the mailing list and if you find some problems, tell us about them in the bug tracking system.

Thanks for everyone who collaborated, we are getting solid as rock. :)

Um pouco mais sobre “Don’t Repeat Yourself”

Por Carlos Brando em 12 de Março de 2009 | 1 comentário

Sim, ainda tem muita coisa a ser dita sobre DRY. Como eu disse no primeiro artigo sobre este assunto, “Don’t Repeat Yourself” não é apenas uma regra, conceito ou boa prática, é uma filosofia. Então vamos filosofar mais um pouco sobre isto…

Li há um tempo atrás no livro The Pragmatic Programmer que nós programadores estamos sempre em modo de manutenção. Isto é uma verdade já que raramente escrevemos código original. Se pararmos para pensar, um código só pode ser considerado novo por alguns minutos após termos lhe escrito pela primeira vez, pois poucos tempo depois você certamente terá de revisitá-lo e alterá-lo. Assim, chegamos a conclusão de que gastamos mais do nosso tempo dando manutenção em um código já criado, do que criando um código original.

3213447769_57bcd2ec05

Programadores estão sempre em modo de manutenção

Você cria um trecho de código, para alterá-lo logo em seguida. Cria mais um pouco de código e então precisa voltar e corrigir um bug encontrado. Escreve mais alguma coisa, e então perde algumas horas refazendo um código que lhe pareceu mau escrito (refactoring).

Don’t Repeat Yourself” tem a pretensão de simplificar a manutenção de nossos projetos tornando-os flexíveis. Por isto é um conceito que deve ser levado muito a sério por qualquer programador que se preze, independente de qual linguagem esteja utilizando.

No caso do Ruby on Rails, embora isto também seja verdade para outras linguagens e frameworks, temos a nossa disposição milhares de gems e plugins que simplificam nossa vida, evitando a duplicação desnecessária de código e facilitando a manutenção do projeto. Também temos a liberdade de criar nossas próprias bibliotecas ou módulos de uma forma muito simples e rápida, afim de evitar repetições em nosso código.

Mas uma outra coisa que também é importante comentar quando falamos em DRY são as ferramentas geradoras de código. Quem trabalha com Rails já está acostumado a utilizar alguns scripts, como os famosos ./script/generate migration, ./script/generate scaffold ou se você utiliza o Rspec em seu projeto também deve usar o ./script/generate rspec_scaffold.

Estas ferramentas são ótimas e economizam muito do nosso tempo. Mas nem sempre os scripts existentes cobrirão todas as suas necessidades, então surgem algumas perguntas: Em que momento se torna prático gastar meu tempo construindo algo assim? Talvez seja necessário algumas horas ou até um dia inteiro para se construir um bom gerador de código, além do esforço necessário em manter o seu código e ensinar os outros programadores a utilizá-lo. Como decidir se o retorno deste investimento é o suficiente para justificar a criação de algo assim?

Falarei mais sobre isto no próximo artigo.

Rails é difícil por causa do Ruby

Por Carlos Brando em 09 de Março de 2009 | 19 comentários

Eu já conversei com muitos programadores PHP e Java que gostam das ideias e conceitos do Rails, mas que têm medo de avançar em virtude do Ruby. O argumento é que uma vez que eles já sabem PHP ou Java, teriam menos trabalho se usassem uma ferramenta similar (como um port) ao Rails para estas linguagens. Eu realmente não penso assim.

Ruby é uma linguagem surpreendentemente simples para se aprender o básico. Sim, há um monte de coisas mais avançadas sobre metaprogramação, mas você realmente não precisa chegar até lá para começar a fazer alguma coisa. E provavelmente você não irá. O caminho necessário para começar a produzir algo é muito mais curto do que você pensa.

Afinal, Ruby não é LISP nem Smalltalk. Não é um mundo completamente novo se você estiver vindo de PHP ou Java. Muitos dos conceitos e construções são iguais. O código será muito semelhante na maioria dos casos, só que mais sucinto.

Aprenda Ruby no mesmo tempo que outro framework

Eu tenho argumentado que a maioria dos programadores poderia aprender Ruby aproximadamente no mesmo tempo que levariam para aprender um outro framework para sua linguagem atual. Eu sei que parece muito mais assustador aprender uma nova linguagem em vez de apenas um outro framework, mas realmente não é.

A resposta que algumas pessoas que temiam fazer isto, mas que fizeram de qualquer forma, me deram é: Por que não fazer isto logo de uma vez?

Aprenda fazendo algo real que lhe interessa

waterjumplake0eachamathertontablelandsx230

Além disso, falando da minha própria experiência de aprendizagem do Ruby, eu realmente recomendo que você tente fazer algo real. Não basta apenas começar com o básico da língua no nada. Escolha algo que você realmente deseja fazer e simplesmente comece a fazê-lo um passo de cada vez. Você aprenderá a medida que avança, e terá a motivação necessária para continuar uma vez que as coisas comecem a funcionar.

Portanto, não desista de aprender Rails porque você não sabe Ruby. Seus temores de começar do zero novamente, rapidamente abrirão caminho para a alegria de uma nova linguagem e você começará a utilizar o Rails como uma verdadeira recompensa. Entrem, a água está ótima!


Este texto é uma tradução do artigo “Myth #5: Rails is hard because of Ruby” escrito por David Heinemeier Hansson, criador do Rails.

Rails Way #5: Don’t Repeat Yourself

Por Carlos Brando em 06 de Março de 2009 | 7 comentários

solve-main
Uma das filosofias mais adotadas por programadores Ruby no mundo todo e amplamente evangelizada pelos maiores nomes da programação, independente da linguagem ou comunidade com o qual está mais envolvido é o “Don’t Repeat Yourself” (Não se repita, ou simplesmente DRY).

DRY é mais do que apenas uma boa prática de desenvolvimento, é uma filosofia que envolve evitar repetições. Trechos de código repetidos na maior parte dos casos (se não em todos) somente tornam nosso código mais obscuro e inconsistente. Quando repetimos trechos de código em nosso projeto ou mesmo em projetos diferentes, estamos aumentando a complexidade de gerenciamento e dificultando mudanças.

Ao criar código reutilizável estamos facilitando nossa vida no longo prazo. Se uma alteração importante é necessária para aumentar a segurança de seu sistema de autenticação, será muito mais fácil realizá-la se você estiver usando uma biblioteca única para este fim em todos os seus projetos. Mas imagine o trabalho que terá se cada projeto em sua empresa utilizar um sistema único de autenticação criado especialmente para ele.

Quando DRY é aplicado com sucesso em seu projeto ou empresa, a modificação de um único elemento não afetará nenhuma outra parte do seu sistema, com exceção de elementos intrincadamente relacionados.

O simples fato de criar bibliotecas não necessariamente significa que você está sendo DRY. Sistemas como o Enterprise Java Beans embora não exijam que você repita código em Java, lhe obrigam a duplicar arquivos de configuração. Isto não é ser DRY. (Uma nota aqui: Estou totalmente por fora do mundo Java e é possível que isto tenha mudado ou melhorado. Minha intenção é apenas exemplificar.)

O ActiveRecord do Rails é um excelente exemplo de uma biblioteca DRY. Não é necessário criar nenhum tipo de arquivo de configuração, e nem mesmo copiar e colar código entre seus modelos.

“Don’t repeat yourself” não é somente sobre duplicar trechos de código, também tem muito a ver com o comportamento funcional do seu código. Composição e herança em linguagens orientadas a objetos foram criados exatamente para suportar este tipo de filosofia. A idéia por trás do DRY é não só evitar duplicações de código, mas também múltiplas e divergentes maneiras de se realizar a mesma tarefa.

DRY também diz que cada pedaço do seu sistema de informação deve possuir uma representação única e inequívoca. Estou falando do seu banco de dados, seu esquema de testes, seu dispositivo de deploy e até mesmo da documentação do seu sistema.

Um projeto de software é muito mais do que o seu código. Você deve encontrar uma forma única de representar cada um dos recursos envolvidos na criação de seus projetos, caso contrário você terá de manter múltiplas representações diferentes de cada recurso, e no caso de uma mudança se prepare para ter muita dor de cabeça. E mudanças acontecem o tempo todo. Não se repetir é importante se desejar ser flexível quanto às alterações em seu sistema.

Quando estamos falamos apenas de código, a criação de uma biblioteca ou um módulo pode ser o suficiente para evitar repetições. Mas no que diz respeito ao banco de dados, por exemplo, talvez seja necessário uma outra abordagem como a criação de uma ferramenta geradora de código ou um sistema de automação, apenas para citar alguns exemplos.

Obviamente DRY não é infalível, em alguns casos o esforço para manter uma biblioteca única para todos os seus projetos, ou para evitar determinados tipos de duplicações em seus códigos pode ser muito maior do que o esforço necessário ao manter cópias diferentes do mesmo código.

“Don’t Repeat Yourself” – Ruby on Rails foi criado com este conceito em mente. Quase tudo que o fazemos no desenvolvimento de projetos com Rails visa evitar duplicações e repetições, mesmo quando falamos de banco de dados e testes. Por este motivo é que “não se repetir” se tornou o principal lema dos desenvolvedores Rails.

Por Carlos Brando em 05 de Março de 2009 | 3 comentários

Uma dica: Use subdiretórios para agrupar imagens por recursos. Ex.: images/people/add.gif vs. images/add_person.gif.

Dica de Ryan Singer

Ruby 1.9 #1: Argumentos em blocos

Por Carlos Brando em 04 de Março de 2009 | 5 comentários

O Ruby 1.9 está ai e já passou da hora de começarmos a ver quais são algumas das novidades mais importantes desta nova versão da nossa linguagem de programação preferida.

À partir da versão 1.9 argumentos criados dentro de blocos terão seu escopo limitado ao mesmo. Para entender melhor, vejamos um exemplo de código executado na versão 1.8.6 e logo em seguida na versão 1.9:

i = "Olá"
3.times { |i| puts i }
puts i
# 0
# 1
# 2
# 2

Note que no código acima ao alterar a variável i dentro do bloco (o método times atribui um novo valor a cada execução) acabamos também alterando a variável com o mesmo nome que foi declarada fora do bloco. Embora isto não seja um bug, mas sim uma característica do Ruby nesta versão, raramente (talvez nunca) vamos desejar este comportamento.

Agora o mesmo código sendo executado na versão 1.9:

i = "Olá"
3.times { |i| puts i }
puts i
# 0
# 1
# 2
# "Olá"

Desta vez a execução do bloco não alterou a variável externa i. Toda variável criada dentro de um bloco no Ruby 1.9 só existirá dentro do escopo do bloco, por isto cuidado com seus códigos malucos ao migrar para esta nova versão!

Como ajudar na tradução dos Rails Guides

Por Carlos Brando em 02 de Março de 2009 | 3 comentários
docrails

Rails Guides em português (em breve)

Não estou trabalhando diretamente nisto, mas quero demonstrar o meu apoio ao projeto de tradução dos Rails Guides.

O Rails Guides é com certeza o maior projeto de documentação do Ruby on Rails em atividade. Diversos guias cobrem praticamente todas as bibliotecas e funcionalidades do framework, com dicas práticas e exemplos de código.

Quem está por trás deste projeto de tradução é o Cassio Marques, mas muitos outros membros da comunidade Rails brasileira estão apoiando o projeto e colaborando com traduções e revisões.

Para os que desejam participar foi preparado um guia com instruções de como proceder e com uma lista do que pode ser feito.

Parabéns a todos os envolvidos no projeto!

PS.: A imagem acima foi descaradamente compiada do blog do Daniel Lopes.

Rails Way #4: Métodos destrutivos ou somente perigosos?

Por Carlos Brando em 27 de Fevereiro de 2009 | 2 comentários

O último artigo desta série levantou uma certa polêmica em alguns pontos. Quero deixar claro que entendo muito bem que existem situações em que não é possível ou mesmo prático utilizar as sugestões descritas aqui. Você não deve encarar esta série de artigos como um livro de leis, mas somente como boas práticas adotadas pela maior parte da comunidade de desenvolvedores Rails.

O que quero é exatamente isto, levantar discussões sobre o que é bom ou ruim e o que é realmente prático ou simplesmente moda.

Ao comentar sobre algumas boas práticas ao nomear métodos, mencionei sobre o uso dos sinais de exclamação (!) e interrogação (?) como uma forma de deixar os métodos mais descritivos. Meu erro talvez tenha ocorrido ao usar o nome ‘métodos destrutivos’ quando me referi aos métodos terminados com o sinal de exclamação.

Concordo em dizer que na verdade ‘!’ no fim de um método não necessariamente significa “destrutivo”, mas sim que o método em questão é uma versão mais perigosa de um outro método com o mesmo nome, mas sem o sinal.

Deixe-me explicar isto melhor

2990809708_b26fb9ef8c

O sinal ! no nome de um método serve como um alerta de “perigo”

O uso da expressão ‘método perigoso’ é relativo. Dizer que um método terminado com ! é perigoso, não diz nada se você não possuir um outro método similar menos perigoso e sem o sinal de exclamação.

Assim, a regra número um é que todo método terminado com ! deve vir acompanhado de um outro método com o mesmo nome, mas sem o sinal.

No Ruby e também no Rails encontramos muitos casos assim. Por exemplo, temos o método gsub! que é mais perigoso que o seu companheiro gsub. Assim como também temos o método exit! que é a versão mais perigosa do método exit, e assim por diante.

Alguns acreditam que devem usar o sinal ! apenas quando o método alterar a sua própria instância. Embora muitos método perigosos façam isto, esta não a finalidade do sinal de exclamação. No próprio Ruby encontramos métodos que tem esta característica mas que não são considerados perigosos, como os métodos Array#pop e Array#push, apenas para citar alguns exemplos.

Devemos apenas fazer uso do sinal ! quando criarmos um método que represente mais perigo que outro já criado. Tome como exemplo os métodos save e save! do ActiveRecord. O primeiro método simplesmente grava o registro no banco de dados e retorna verdadeiro ou falso de acordo com o resultado do procedimento. Utilizando o segundo método, caso algo dê errado não teremos de volta apenas um booleano falso, teremos o disparo de uma exceção, o que pode representar um certo risco se o seu aplicativo não estiver preparado para isto. Desta forma podemos considerar este método mais perigoso que o primeiro, merecendo assim a adição do sinal ! no final de seu nome.

A conclusão é que o uso de “!” no nome de um método não dirá a você exatamente o que ele fará ou de que forma ele representa perigo. Mas o sinal de exclamação (!) é importante como um alerta de que o método em questão pode representar algum risco se usado de forma impensada.

Um modelo de maturidade para projetos Rails é prático?

Por Carlos Brando em 17 de Fevereiro de 2009 | 17 comentários

Acredito que este seja o assunto da semana nas rodas de desenvolvedores Rails, e como tal eu não poderia deixar de dar minha opinião sobre o assunto.

Obie Fernandez – um personagem conhecido na comunidade Rails mundial graças ao seu famoso livro “The Rails Way”, sua empresa Hashrocket e também pela sua personalidade forte – vem criando uma certa polemica sobre a criação de um modelo para definir a maturidade de uma empresa na criação de projetos Rails. A ideia original é criar um sistema parecido com o que seria um CMM, mas direcionado as melhores práticas de desenvolvimento em projeto Ruby on Rails.

O RMM descreveria os estágios de maturidade através dos quais as empresas de software teriam de passar afim de evoluir seus processos. Na concepção original estes estágios seriam divididos em níveis que iriam de 0 a 3:

RMM0

  • Nenhum processo formal de desenvolvimento
  • Sem cobertura de testes
  • Nenhum padrão de práticas de negócio
  • Análise de falhas estática

RMM1 e RMM2 deveriam ser alguma coisa intermediária, sendo que o RMM1 seria considerado negativo, enquanto o RMM2 seria considerado positivo.

RMM3:

  • Práticas ágeis de desenvolvimento de software
  • 100% de cobertura com testes
  • 100% de programação em pares
  • Padrão formal de práticas de negócio
  • Sistema de aprendizado contínuo e melhoria do processo
  • Testemunhos positivos de clientes
  • Aplicativos Rails implantados com sucesso
  • Outros itens a serem definidos…

Obviamente este itens são apenas ideias, muita coisa ainda estaria faltando se isto estivesse finalizado.

O grande problema levantado por Obie é que muitas empresas que desejam contratar profissionais ou terceirizar o desenvolvimento de softwares em Rails, tem dificuldade em identificar se uma determinada consultoria ou profissional são realmente bons. A criação de um selo como o RMM simplificaria este processo. Teoricamente bastaria o contratante verificar em qual nível do RMM a prospectiva empresa se encontra, e isto definiria a qualidade dos serviços prestados e traria segurança ao contratante.

É exatamente neste ponto que discordo totalmente de Obie. Possuir um “selo” de qualidade não indica realmente que a empresa é de qualidade. Existe muito mais envolvido nisso do que simplesmente adotar boas práticas.

A empresa pode adotar como regra todas as sugestões dadas no RMM e ainda assim contratar profissionais ruins e/ou desmotivados. Pode adotar o sistema de programação em pares de uma forma que não seja produtiva. Enfim, todos os itens são relativos. Acredito que a qualidade de um empresa depende muito mais dos profissionais contratados e do quão motivados eles estão, não desconsiderando nenhuma destas boas práticas.

Sim, RMM tem tudo a ver com certificações. Talvez não pareça, mas no fundo o conceito é o mesmo. Uma certificação é como o exame de motorista. Minha esposa conseguiu tirar sua carta de motorista na primeira tentativa à alguns meses atrás, mas até hoje ela não consegue dirigir em uma avenida mais movimentada que temos perto de casa. Isto se dá porque as escolas não ensinam as pessoas a dirigir, mas sim a passar no exame de motorista.

O mesmo se dá com certificações, as pessoas estudam para passar na avaliação, mas isto não significa que estão preparadas para os desafios da vida real. Contratar um profissional somente pela certificação, seria como contratar uma pessoa que acabou de conseguir sua habilitação para ser o motorista de sua família.

345246158_d34e3a4b41

Escolher um profissional somente porque ele tem uma certificação é como escolher um motorista somente porque ele tem habilitação para dirigir

Contratar uma empresa somente porque ela segue uma série de regras definidas por uma outra pessoa ou organização, e por isto conseguiu um “selo de qualidade” representa o mesmo tipo de risco.

Ao contratar uma empresa para desenvolver um software, seja em Rails ou em qualquer outra tecnologia, entre em contato com outros clientes que já foram atendidos pela empresa. Procure saber quais projetos criados pela empresa foram concluídos com sucesso. Tente descobrir mais sobre os profissionais que compõem o seu time de desenvolvimento. Esta é a melhor garantia de que você estará contratando a empresa certa para o sucesso do seu projeto.

Temos ótimos blogueiros em nossa comunidade de programadores brasileiros e muitos artigos são escritos sobre os mais diversos assuntos relacionados ao Ruby e ao Rails. Mas eu sempre senti falta de uma fonte única de noticias sobre o que acontece no mundo Ruby on Rails aqui no Brasil.

A primeira tentativa de trazer isto aos desenvolvedores tupiniquins foi com o Rails Podcast Brasil, um podcast semanal com as principais noticias sobre novas bibliotecas, técnicas e polemicas que envolviam o Ruby on Rails. O podcast sempre foi um sucesso de audiência e chegou até a sua 39º edição. Mas o formato de podcast tinha alguns problemas: as noticias chegavam com uma semana de atraso, você precisava dedicar pelo menos uma hora para ouvir todas as noticias e ele também consumia muito tempo para ser produzido. Mesmo assim, não desanime, teremos novidades sobre o podcast em breve…

Durante um bom tempo meditei sobre qual seria a melhor maneira de trazer as noticias o mais rápido possível para a comunidade, de uma forma que até mesmo o mais ocupado desenvolvedor pudesse se atualizar rapidamente. Encontrei a solução na forma como eu mesmo resolvo este problema. Eu mantenho alguns sites em meu leitor de feeds e sempre que posso me atualizo, mas dou prioridade para sites que agregam noticias, como o famoso Ruby Inside de Peter Cooper.

O problema é que uma boa parte da nossa comunidade, principalmente os iniciantes não tem acesso a informações em inglês, e não existe nenhum site em português com o mesmo conteúdo de sites como Ruby Inside e Rails Inside. Pensando nisso, no inicio do ano entrei em contato com Peter Cooper buscando uma forma de trazer o conteúdo destes sites para a comunidade brasileira. E consegui!

Agora tenho o prazer de anunciar o:

logo-br

Ruby Inside Brasil!

O site é um franquia da edição americana do Ruby Inside, e trará para o público brasileiro os mesmos artigos publicados lá fora, totalmente em português. Além disso também teremos muito conteúdo nacional, com artigos escritos por desenvolvedores nacionais e uma cobertura completa de tudo o que acontece com Ruby e Rails por aqui.

Não estou sozinho nesta empreitada, conto com um time muito motivado e cheio de feras: Eliézer Pimentel, José Gomes, Levy Carneiro, Luís Gustavo e Rafael Rosa. Vocês irão conhecer cada um deles um pouco melhor no futuro com uma série de artigos que estou preparando sobre o projeto.

O Ruby Inside Brasil acabou de nascer, mas já conta com mais de 20 artigos traduzidos. Algumas empresas brasileiras, como a Plano Bê, também já tem demonstrado seu apoio pelo projeto.

Se você apóia a idéia, existe algumas coisas que você pode fazer, como espalhar a noticia de todas as formas possíveis, através do seu blog, twitter, contando para seus amigos, etc. Mas se você representa uma empresa, também pode patrocinar o site. Teremos o maior prazer em incluir um anúncio da sua empresa ou projeto em formato de banner nas páginas do Ruby Inside Brasil, para isto basta entrar em contato conosco.

Depois do Rails Podcast Brasil, do Rails Summit Latin America e tantos outros projetos de evangelização de Rails no Brasil, espero que este site possa ser o próximo passo em direção ao sucesso do Rails em nosso país.

Não sou uma pessoa supersticiosa, mas hoje é sexta-feira (13) e é melhor não abusar, então vamos manter a tradição e comentar sobre mais um rubismo, ou se preferir, mais uma boa prática de programação que todos os desenvolvedores deveriam adotar independente da linguagem que usem.

Dar nomes para classes, módulos, métodos e variáveis é uma tarefa complicada em alguns casos. Com certeza você em algum momento de sua carreira já ficou na dúvida sobre que nome dar a um determinado método ou variável. Talvez até mesmo apelou para algum colega de trabalho em busca de alguma sugestão.

A regra é: o nome de uma classe, módulo, método ou variável deve ser o mais óbvio possível. Em muitos casos, um programador totalmente concentrado no código que está escrevendo não se apercebe de que o que lhe parece óbvio naquele momento, não será tão óbvio na segunda-feira, depois de um fim de semana com a família. E se ele próprio pode ficar um pouco perdido com nomes estranhos e abreviações, imagine quando um outro programador sem o contexto necessário for fazer uma manutenção naquele código.

water

Óbvio, mas sem exageros... hehe

Andy Lester em 2004 escreveu em seu artigo “The world’s two worst variable names”, que o pior nome para se dar a uma variável é data. Como no exemplo abaixo:

data = User.find(10)
puts "Nome: = #{data.name}"

Eu já vi muito este tipo de coisa, e tenho certeza de que você também. Mas que droga de nome é este? É óbvio que o que está armazenado em uma variável é um dado (data), mas que tipo de dado, é a pergunta a ser feita. Neste caso especifico renomear a variável para user já faria uma enorme diferença. Nomes como data, ret e temp não querem dizer nada.

Agora vem a melhor (ironicamente) parte, o segundo pior nome para se dar a uma variável é data2 e suas variações. Veja só que coisa horrível:

user  = User.find(10)
user2 = User.find(20)
puts "O #{user.name} é amigo do #{user2.name}"

No exemplo acima estou usando um nome descritivo, mas qual é a diferença entre user e user2? Eu preciso ser mais óbvio que isto. No contexto do exemplo acima, alterar a segunda variável para friend, resolveria este problema e tornaria meu código mais descritivo.

Não use abreviações

Não use abreviações, à menos que elas sejam realmente óbvias. E quando eu digo óbvia estou dizendo que deve ser para qualquer um, mesmo alguém que nunca trabalhou em seu código. Não existe problema algum em usar nomes longos e descritivos. Veja por exemplo, o nome deste método:

def thera_class_code_fmt
  # devolve alguma coisa
end

E então? O que este método faz? Para mim parece óbvio, mas você não tem obrigação de saber que ‘thera’ é uma abreviação para therapeutic, assim como ‘fmt’ é para formatted. Não seria melhor se este método se chamasse formatted_therapeutic_class_code?

No próprio Rails podemos encontrar alguns nomes longos e descritivos como convert_number_column_value e class_name_of_active_record_descendant. Em alguns casos nem precisamos olhar a documentação para entender como o método funciona.

Prefixos não são necessários

Prefixos como str, int e coisas do gênero não são necessários se eu der um nome descritivo à variável. Ao ver uma variável chamada age (idade) logo você deduz que ela deve ser do tipo numérica, assim não seria necessário dar a ela um nome estranho como int_age, ou algo parecido. Podemos dizer o mesmo de uma variável chamada name (nome) que obviamente deve ser um objeto do tipo string.

Use os recursos da linguagem

No Ruby também usamos alguns símbolos em nomes de métodos, como ‘?’ e ‘!’. Um símbolo de interrogação (?) no final no nome indica que aquele método deve retorna um booleano true ou false. O sinal de exclamação (!) informa que o método é destrutivo perigoso, o que pode significar duas coisas: no caso de algo dar errado ele devolverá uma exceção ao invés de um simples false, como nos métodos save e save! do Active Record ou que ele alterará a própria instância do objeto, ao invés de devolver uma nova instância, como nos métodos merge e merge!, por exemplo.

Código bilingue?

Embora não exista uma regra escrita para isto, também sou contra nomear variáveis, métodos ou classe em português. Acho que como todo o código já está em inglês, graças as palavras chaves do Ruby, devemos manter absolutamente tudo em inglês também. Isto não é tão difícil assim, já que você pode fazer uso de tradutores e dicionários (online) para encontrar a melhor descrição para eles.

Pense antes de escolher um nome

Algumas vezes, escolher um bom nome pode parecer difícil, e isto pode acabar roubando um pouco do seu tempo. A dica é que você termine de codificar o seu método primeiro, e depois com o contexto formado em sua mente ficará mais fácil dar um nome descritivo para o método e para as variáveis usadas. Se mesmo assim você ficar na dúvida, inclua um comentário com um TODO no seu código, vá tomar um café e quando você voltar com certeza encontrará um bom nome.

Uma das grandes vantagens que encontramos no Ruby e no Rails é que em ambos é extremamente normal encontrar nomes descritivos e tão curtos quanto possível em classe, módulo, métodos e variáveis. POR FAVOR, NÃO ESTRAGUE ISTO.

Rails 2.3: Active Record

Por Carlos Brando em 12 de Fevereiro de 2009 | deixe um comentário

O lançamento do Ruby on Rails 2.3 está muito próximo e eu ainda não comentei sobre algumas novidades por aqui. A idéia desta série não é apenas mostrar as novas funcionalidades, mas explicar e dar exemplos de como elas funcionam na prática, mas alguns dos novos recursos são muito simples e não exigem muitos detalhes. Vejamos alguns relacionados ao Active Record.

Os callbacks do Active Record receberam uma nova implementação que permite o uso combinado das opções :if e :unless no mesmo callback. Você também pode usar um array para definir múltiplas condições:

before_save :update_credit_rating,
            :if => :active,
            :unless => [:admin, :cash_only]

O método find também ganhou uma nova opção :having para filtrar registros agrupados:

Developer.find(:all,
               :group => "salary",
               :having => "sum(salary) >  10000",
               :select => "salary")

Outra funcionalidade importante que temos de volta é o uso de um hash :conditions em relacionamentos has_many. Isto já funcionava no Rails 2.1, parou de funcionar no Rails 2.2 e está de volta no Rails 2.3.

has_many :orders, :conditions => {:status => 'confirmed'}

Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.3 ou superior. Você pode encontrar mais detalhes sobre esta e outras novidades acompanhando a série Rails 2.3.

Faça você mesmo primeiro

Por Carlos Brando em 11 de Fevereiro de 2009 | deixe um comentário

Você nunca deve contratar alguém para fazer alguma coisa sem se esforçar em fazê-la primeiro. Isto vai ensinar-lhe mais do que o necessário para que você possa entrevistar os candidatos, vai permitir que você entenda melhor a natureza do trabalho (preciso mesmo contratar ou podemos terceirizar?) e você saberá exatamente como um trabalho bem feito deve parecer. Isto também vai lhe permitir saber se o trabalho é grande o suficiente para contratar alguém por tempo integral ou se você mesmo poderia fazê-lo.

Jason não me contratou para ajudá-lo no programa Singlefile (extinto) antes de ter uma espécie de protótipo-mal-feito criado através de suas próprias competências em PHP. Eu não contratei Mark para fazer a administração do sistema sem antes perder um verão inteiro configurando um cluster. Jason não trouxe Sarah à bordo para manter o serviço de suporte antes dele mesmo ter tentado fazer isto por alguns anos.

Os benefícios de tentar fazer você mesmo o trabalho antes de contratar alguém não estão somente na hora de realizar uma contratação. Você conseguirá gerenciar muito melhor o trabalho se você em algum momento já o realizou, do que quando você está totalmente no escuro sobre o que precisa ser feito. Você terá empatia quando as coisas não ocorrerem da forma como você esperava e a culpa não for exatamente do funcionário – e também terá voz ativa quando for.

2914363493_73a21ed86a

Ok, nem sempre você deve tentar fazer primeiro...

Não deixe que nomes compridos o assuste. O que um diretor de desenvolvedor empresarial faz? Descubra fazendo você mesmo. Chame algumas pessoas, tente fazer alguns negócios. Você acha que precisa de alguém para realizar testes de usabilidade em seu projeto? Tente fazer você mesmo uma sessão com seus amigos. Não, ele não sairá perfeito. Mas tudo bem. O que você está perdendo nesta execução inicial lhe será reembolsado várias vezes pelos benefícios descritos acima.


Este texto é uma tradução do artigo escrito por David Heinemeier Hansson para o blog Signal vs. Noise, originalmente em inglês.

Remarkable now supports all ActiveRecord validations

Por Carlos Brando em 10 de Fevereiro de 2009 | 7 comentários

Good times! It has been just one week since I announced Diego Carrion and José Valim as members of the Remarkable core team and we already put some effort into making a new shiny release! We are going to cover what’s new on this Remarkable version, step by step.

1. All ActiveRecord validations are supported with all options

In other words, you can write your spec validation macros the same way as you do in ActiveRecord, without consulting the documentation, without worrying if any validation is supported or not, without checking which options are allowed or not. Check it out:

describe User do
  it { should validate_uniqueness_of(:email) }
  it { should validate_presence_of(:email, :password) }
  it { should validate_confirmation_of( :email, :password) }

  it { should validate_acceptance_of(:terms) }
  it { should validate_inclusion_of(:gender, %w(m f), :message => 'whoa! what are you then?') }
  it { should validate_length_of(:password, :within => 6..20) }
  it { should validate_numericality_of(:age, :greater_than_or_equal_to => 18, :allow_nil => false) }

  it { should allow_mass_assignment_of(:password, :email) }
  it { should not_allow_mass_assignment_of(:salt, :hashed_password) }
end

Or if you prefer:

describe User do
  should_validate_uniqueness_of :email
  should_validate_presence_of :email, :password
  should_validate_confirmation_of :email, :password

  should_validate_acceptance_of :terms
  should_validate_inclusion_of :gender, %w(m f), :message => 'whoa! what are you then?'
  should_validate_length_of :password, :within => 6..20
  should_validate_numericality_of :age, :greater_than_or_equal_to => 18, :allow_nil => false

  should_allow_mass_assignment_of :password, :email
  should_not_allow_mass_assignment_of :salt, :hashed_password
end

We updated the wiki and it’s already reflecting the new macros. But you might ask, what happened with the older ones? The older ones are going to be deprecated and you will see a message while running the tests.

What you might have noticed above is that should_protect_attributes now became should_not_allow_mass_assignment_of. This one was based on Shoulda last changes, so who are porting tests from Shoulda gets everything compatible.

2. Pending macros

We are not just bringing macros to Rspec, we are bringng Rspec to macros! So let’s suppose you are doing some code refactoring and you know some tests will fail while you clean the house, what do you do then?

In Rspec, you can do:

xit { should validate_numericality_of(:age) }

Well, now you can do just the same with macros:

xshould_validate_numericality_of :age

And it’s even better because it shows you a nice message:

Example disabled: should validate numericality of age

Yeah!

3. Full I18n support

You know how validations macros (as validate_presence_of) work? Let’s talk about it a little bit.

When you say that we should validate presence of e-mail, we set the e-mail to nil and save the object. Then we search in all error messages in e-mail, if it has a “can’t be blank” message, your validation is working properly and then the test passes, otherwise, the test fails. The problem is, if you change the error message in your application and do not change on the macro, we will never be able to find the message “can’t be blank” and then the tests will always pass.

This is valid for almost rspec matchers, not only on Remarkable. But what’s new is, if you change the message using the I18n YAML files, we will find the message properly and you don’t have to pass :message in your macros. This is new and we are currently the only one doing this.

But remember, if ever you set the message directly in your models like this:

validates_inclusion_of :gender, %w(m f), :message => 'whoa! what are you then?'

Don’t forget to do the same in your macros:

should_validate_inclusion_of :gender, %w(m f), :message => 'whoa! what are you then?'

Deal?

Conclusion

Remarkable is available on GitHub and to install it, just do on your console:

gem sources -a http://gems.github.com/
sudo gem install "carlosbrando-remarkable"

And then on your RAILS_ROOT/config/environment.rb:

config.gem "carlosbrando-remarkable", :lib => "remarkable", :source => "http://gems.github.com/"

Any doubts? Any bug?

We want to hear you! So you can use the Remarkable google group, our bug tracking system, Github comments, whatever suits you better!

See you there!

Evento: Ruby e Rails no Mundo Real

Por Carlos Brando em 09 de Fevereiro de 2009 | 5 comentários

Mais um evento sobre Ruby on Rails em São Paulo, desta vez promovido pelo grupo Guru-SP (Grupo de Usuários Ruby de São Paulo).

A idéia do evento é exibir palestras práticas com temas que tratarão de assuntos relacionados ao dia a dia de profissionais Rails, como controle de versão, testes, treinamentos, servidores de aplicação e mercado de trabalho (brasileiro e exterior).

O evento já está confirmado para o dia 4 de abril de 2009 e será realizado no Century Flat Paulista que fica na Rua Teixeira da Silva, 647 no Paraíso.

Veja abaixo a relação de palestras, palestrantes e horários:

8h00: Boas Vindas, Credenciamento e Retirada do Material do Congressista

9h15: Criando um Instant Messenger usando Rails por Vinícius Baggio Fuentes

10h30: Ruby, Rails e empreendedorismo mini-palestra por Hugo Lima Borges

11h00: Integrando Ruby e Java para facilitar a vida por Marcelo Castellani

13h00: Outsorcing, ou como trabalhar para empresas gringas por Rodrigo Franco

14h00: GlassFish on Rails: Escalabilidade e Confiabilidade por Mauricio Leal

15h00: Só imaturos não testam por Carlos Brando

16h00: O que é e como funciona o RubyLearning mini-palestra por Willian Molinari

16h15: Utilizando Gitorious nos seus projetos por Fabio Akita

Para os que se cadastrarem até o dia 6 de março a inscrição para o evento sai por 49 reais, o que representa custo muito pequeno, levando-se em conta o nível das palestras e palestrantes. Após esta data, o valor é de 69 reais.

Para mais informações acesse a página oficial do evento.

Rails Way: Variáveis de Instância, Controllers e Views

Por Carlos Brando em 06 de Fevereiro de 2009 | 13 comentários

Mais uma sexta-feira e mais um artigo da série Rails Way, onde vou pouco a pouco mostrando a forma como os Rubistas mais experientes costumam programar no Ruby on Rails.

Programadores iniciantes rapidamente ficam fascinados com o Ruby e principalmente com o Rails, e por serem uma linguagem e framework com uma curva de aprendizado muito curta é comum que ao terminarem seu primeiro projeto em Rails, percam um pouco o interesse em entender como determinadas coisas funcionam, assimilando tudo que o Rails faz como pura mágica.

Isto é extremamente prejudicial ao programador iniciante e pode levá-lo a se tornar um programador “experiente” com pouco ou nenhum conhecimento real sobre o funcionamento interno da sua ferramenta de trabalho.

A ideia desta série de artigos é expor algumas boas práticas de desenvolvimento ao mesmo tempo em que tento explicar de uma forma simples como as engrenagens funcionam. Por exemplo, já se perguntou como um controller e uma view compartilham as mesmas variáveis de instância?

Por definição uma variável de instância só existe dentro de uma única instância de um objeto. Mas quando estamos falando de controllers e view, estamos falando de dois objetos diferentes que compartilham as mesmas variáveis.

# books_controller.rb
class BooksController < ApplicationController
  def index
    @books = Book.find(:all)
  end
end
<!-- index.html.erb -->
<% for book in @books %>
   <%= book.title %>
<% end %>

Nos exemplos acima estou definindo uma variável de instância @books dentro do controller, e eu simplesmente assumo que a variável também estará disponível na view.

Note que meu controller é uma extensão da classe ApplicationController que por sua vez é uma extensão da classe ActionController::Base e por isto é uma instância desta classe. Por outro lado a minha view é uma instância da classe ActionView::Base. Ou seja, meu controller é uma instância de um objeto enquanto minha view é uma instância de um outro objeto totalmente diferente.

Então como é possível compartilhar uma variável de instância quando temos duas instância de objetos diferentes? Será mágica? Não, a resposta é mais simples do que você imagina.

O Rails acrescenta à classe Object um método chamado copy_instance_variables_from que faz exatamente o que o nome diz, copia variáveis de instância de uma classe para outro. Você pode até mesmo brincar um pouco com este método no console. Abra o terminal e após digitar o comando irb, copie e cole o código abaixo e veja o resultado:

require 'rubygems'
require 'active_support'

class A
  attr_reader :x, :y
end

class B
  def initialize
    @x = 'valor copiado da classe B'
    @y = 11
  end
end

a = A.new
b = B.new

puts a.x # => nil
puts a.y # => nil

a.copy_instance_variables_from(b)

puts a.x # => "valor copiado da classe B"
puts a.y # => 11

Acabamos de copiar todas as variáveis de instância de um objeto para outro. É exatamente assim que acontece com controllers e views.

O que acontece por debaixo dos panos é que quando o método render do controller é executado, primeiro ele copia todas as variáveis de instância que você criou para dentro de apenas uma variável chamada @assigns, que funciona como um Hash. E ao criar uma uma nova view, ele faz uma copia desta variável (@assigns com todas as suas variáveis dentro) para o novo objeto. Simples não?

O inferno das variáveis

O que tenho visto muitas vezes é que alguns programadores tem abusado desta facilidade que o Rails oferece, criando inúmeras variáveis de instância no controller para recuperar todo tipo de informação na view.

Manter muitas variáveis complica o gerenciamento do código, e em alguns casos acabamos até mesmo fazendo chamadas repetidas à associações de um modelo sem se dar conta disso, causando um problema de performance em nosso projeto.

O ideal é que você compartilhe apenas uma variável de instância entre seu controller e sua view. Desta forma todas as chamadas para associações serão realizadas “on demand” evitando o consumo indevido de recursos e tornando a manutenção do código mais simples.

97493713_c72ee9a7bd

Apenas uma variável de instância entre seu controller e sua view

Isto não quer dizer que você não possa compartilhar outras variáveis quando necessário. Mas é importante que você analise a real necessidade de se fazer isto. Por exemplo, é mais prático criar um helper current_user para recuperar o usuário atual do que sempre armazená-lo em uma variável @current_user.

Se no primeiro exemplo você precisasse recuperar também todos os livros relacionados ao livro atual, talvez parecesse razoável criar uma segunda variável @related_books contendo estes livros. Mas se você colocar em prática a primeira dica desta série e acrescentar o método related_books ao modelo Book, você poderá usar @book.related_books na sua view. Evitando a criação desnecessária de mais uma variável e deixando seu código mais limpo e organizado.

Usem de bom senso.

Rails 2.3: Nested Transactions

Por Carlos Brando em 05 de Fevereiro de 2009 | 3 comentários

Outro recurso que também foi muito solicitado e estará disponível com a versão 2.3 do Rails é uma melhoria nas nested transactions (transações aninhadas).

Atualmente no Rails já podemos aninhar transações, ou em um português mais simples podemos colocar uma transação dentro de outra. Veja um exemplo:

User.transaction do
  User.create(:username => 'Kotori')
  User.transaction do
    User.create(:username => 'Nemu')
    raise ActiveRecord::Rollback
  end
end

User.find(:all) # => empty

Resumindo o exemplo acima: Criei uma transação e inclui um novo usuário no banco, então criei uma segunda transação dentro da primeira e inclui um segundo usuário, e no fim disparei uma exceção que faz com que a primeira transação e todas as suas filhas sejam desfeitas como você pode ver no resultado do método find.

A novidade é a opção :requires_new. Quando usada em uma sub-transação, caso alguma coisa dê errado somente as alterações feitas dai em diante é que serão desfeitas. Veja um novo exemplo, agora com este recurso habilitado:

User.transaction do
  User.create(:username => 'Kotori')
  User.transaction(:requires_new => true) do
    User.create(:username => 'Nemu')
    raise ActiveRecord::Rollback
  end
end

User.find(:all) # => Returns only Kotori

Como você pode ver no retorno do método find, ao realizar o rollback somente a inclusão do segundo usuário foi desfeita, já que estou usando a opção :requires_new habilitada na segunda transação.

Nem todo banco de dados tem suporte real a nested transactions. Na verdade, até o momento somente o MS-SQL tem esta funcionalidade. Mas não se preocupe se você estiver usando outro banco de dados, o Active Record consegue emular nested transactions usando savepoints.

ATENÇÃO: Caso você esteja usando o MySQL, então não faça operações DDL em nested transactions que estiverem emulando savepoints. Ou seja, não tente executar algo como ‘CREATE TABLE’ nestes blocos. Isto acontece porque o MySQL automaticamente libera todos os savepoints após executar uma operação DDL. Então quando a transação terminar e tentar liberar os savepoints criados, ocorrerá um erro no banco já que todos os savepoints foram liberados antes da hora. Para entender melhor, veja o exemplo abaixo:

# INICIO
Model.connection.transaction do
  # CRIA O SAVEPOINT active_record_1
  Model.connection.transaction(:requires_new => true) do
    # active_record_1 é automaticamente liberado
    Model.connection.create_table(...)
  end # LIBERA o savepoint active_record_1

  # ^^^^ BOOM! database error!
end

Apesar deste pequeno detalhe, em todos os outros casos este recurso tem funcionado perfeitamente.


Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.3 ou superior. Você pode encontrar mais detalhes sobre esta e outras novidades acompanhando a série Rails 2.3.

Rails 2.3: Nested Attributes

Por Carlos Brando em 04 de Fevereiro de 2009 | 7 comentários

Durante muito tempo a funcionalidade mais requisitada ao core team do Rails era a simplificação do gerenciamento de múltiplos modelos em apenas um formulário. Eu mesmo cheguei a comentar sobre uma nova opção chamada :accessible que facilitaria atribuições em massa em objetos ActiveRecord (aqui e aqui).

Infelizmente este recurso foi incluído ao Rails cedo demais, já que ele só dava suporte a nested models (é como chamamos os modelos que estão “acoplados” a um outro modelo, como quando usamos belongs_to ou has_many) durante a criação dos objetos e por isto ele foi removido afim de ser aprimorado.

No Rails 2.3 esta funcionalidade volta a existir, mas de uma maneira diferente. A primeira coisa que devemos fazer é informar ao modelo que ele se beneficiará deste recurso incluindo uma chamada ao método accept_nested_attributes_for, como no exemplo:

class Project < ActiveRecord::Base
  has_many :tasks

  accept_nested_attributes_for :tasks, :allow_destroy => true
end

Como visto acima estou “ligando” a atribuição em massa para o modelo Task via o modelo Project. Isto também vale para qualquer tipo de relacionamento, como belongs_to, has_one, has_many e has_and_belongs_to_many.

Uma vez feito isto, agora eu posso criar, editar e apagar tarefas (tasks) através do objeto Project:

# Adicionando uma nova tarefa ao projeto
@project.task_attributes = { 'new_1' => { :name => 'Task 1' } }
@project.task #=> [ <#Task: name: 'Task 1'> ]
@project.task.clear

# Adicionando duas tarefas ao projeto
@project.task_attributes =
  { 'new_1' => { :name => 'Task 1' }, 'new_2' => { :name => 'Task 2' } }
@project.save
@project.task #=> [ <#Task: name: 'Task 1'>, <#Task: name: 'Task 2'> ]

# Alterando a primeira tarefa (assumindo o id == 1)
@project.task_attributes = { '1' => { :name => 'My Task' } }
@project.save

# Alterando a segunda tarefa (id == 2) e incluindo uma nova
@project.task_attributes = {
  '2' => { :name => 'My Second Task' },
  'new_1' => { :name => 'Task 3' } }
@project.save

# Apaga o último registro (id == 3)
@project.task_attributes = { '3' => { '_delete' => '1' } }
@project.save

Talvez neste momento você esteja se questionando sobre estes formatos estranhos, como ao apagar um registro. Sim, estes hashs são meio confusos mesmo, mas eles não foram criados para serem usados desta maneira. O uso prático deste novo recurso está na criação de formulários:

<% form_for @project do |project_form| %>
  <div>
    <%= project_form.label :name, 'Project name:' %>
    <%= project_form.text_field :name %>
  </div>

  <!-- PRESTE ATENÇÃO AQUI -->
  <% project_form.fields_for :tasks do |task_form| %>
      <p>
        <div>
          <%= task_form.label :name, 'Task:' %>
          <%= task_form.text_field :name %>
        </div>

        <% unless task_form.object.new_record? %>
          <div>
            <%= task_form.label :_delete, 'Remove:' %>
            <%= task_form.check_box :_delete %>
          </div>
        <% end %>
      </p>
    <% end %>
  <% end %>

  <%= project_form.submit %>
<% end %>

Ao definir project_form.fields_for :tasks estamos dizendo que aquele trecho do formulário deve usar o recurso de atribuição em massa para criar, editar ou apagar uma tarefa (task) já existente.

Caso uma das validações da classe Task não passe (imagine que esta tenha um validates_presence_of :name e que eu deixei o campo name em branco), a mensagem correspondente a esta validação será copiada para a classe pai, no caso para a classe Project e estará acessível através do método error_messages_for dela.

Este novo sistema também conta com o recurso de transações. Isto significa que ao realizar uma série de operações de uma só vez, se uma der errado, nenhuma delas será efetivada. Lembre-se apenas que como toda transação no Rails, embora no banco de dados nada aconteça, na instancia do seu objeto ele ainda continuará com as alterações marcadas.

O mais importante em tudo isto é que o código em seus controllers continuarão exatamente da mesma forma como já é hoje. Nenhuma alteração é necessária. Seguindo os exemplos acima, veja como ficaria meu controller:

class ProjectController < ApplicationController

  def create
    @project = Project.new(params[:project])
    if @project.save
      redirect_to(project_path(@project))
    else
      render(:action => :new)
    end
  end

  def update
    @project = Project.find(params[:id])
    @project.update_attributes(params[:project]) ?
      redirect_to(project_path(@project)) : render(:action => :edit)
  end

end

Nada mudou correto?

Eloy Duran, o programador responsável por este novo recurso, tem um projeto no GitHub mostrando mais detalhes sobre o seu funcionamento. Recomendo que você dê uma olhada neste formulário em especial, onde ele mostra como incluir múltiplas tarefas no mesmo projeto.


Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.3 ou superior. Você pode encontrar mais detalhes sobre esta e outras novidades acompanhando a série Rails 2.3.

Rails 2.3: Formatted Routes

Por Carlos Brando em 03 de Fevereiro de 2009 | 6 comentários

No Rails 2.3, ao acessar nossas rotas nomeadas não teremos mais métodos como formatted_post_path ou formatted_new_user_path. Estes métodos dinâmicos foram removidos com o objetivo de melhorar o consumo de memória no Rails.

Mas isto não significa que não teremos mais a funcionalidade de rotas formatadas. Elas continuam existindo, mas devem ser acessadas de outra maneira. Vejamos alguns exemplos comparando a forma atual e a nova forma:

# atual
formatted_post_path(post, :xml)
# novo
post_path(post, :format => :xml)

# atual
formatted_new_user_path(:json)
# novo
new_user_path(:format => :json)

É uma mudança muito pequena, mas que internamente tem um impacto significativo no consumo de memória dos processos Rails, principalmente se você possui muitas rotas em seu projeto.

Caso você esteja em um processo de migração deve atentar a esta alteração.

O Rails 2.3 já está em sua versão RC1 e em poucos dias devemos ter sua versão final lançada, mas esta série continuará expondo algumas das novidades que encontraremos nesta versão.


Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.3/3.0 ou superior. Você pode encontrar mais detalhes sobre esta e outras novidades acompanhando a série Edge Rails.

Remarkable 2.1.7

Por Carlos Brando em 02 de Fevereiro de 2009 | 4 comentários

Acabou de sair a versão 2.1.7 do Remarkable que conta com algumas novidades.

As macros have_index e have_indices agora contam com a opção :unique que verifica se o índice criado na tabela é único.

it { should have_index([:email, :name]).unique }
# ou
should_have_index [:email, :name], :unique => true

Além disso, com o lançamento da nova versão do RSpec alguns ajustes no projeto foram necessários. Estes ajustes foram feitos e agora o Remarkable deve funcionar perfeitamente após atualizar o RSpec.

Mas a novidade mais importante é a adição de dois novos membros ao core team do projeto:

fc66c82eada8b3869009812a61cf5993jpeg

Diego Carrion: Muito conhecido pelo seu blog MouseOver Studio, e foi o responsável pela atualização do projeto para a nova versão do RSpec.


e837f6b7fd146ab16ed3d663476c063ejpeg José Valim: Um dos responsáveis pelo excelente Pagestacker! Iniciou seu trabalho no Remarkable incluindo novos matchers.


Ambos participam ativamente em vários projetos open-source e formarão comigo um time de desenvolvimento para o Remarkable.

Para atualizar a sua versão do Remarkable execute no terminal:

# Isto só precisa ser executado uma vez
gem sources -a http://gems.github.com

# Para instalar
sudo gem install carlosbrando-remarkable
Propaganda: