Hoje completa exatamente três anos desde que comecei a escrever neste blog. São mais de 780 artigos publicados, 3.800 comentários e 19.000 spams recebidos e interceptados pelo Akismet.
Neste intervalo tive a oportunidade de publicar dois livros sobre as principais novidades das versões 2.1 e 2.2 do Ruby on Rails. O mais interessante é que o conteúdo de ambos os livros foram extrações de artigos escritos para este blog.
Outra fase muito legal foi o ano do Rails Podcast Brasil. Onde Fábio Akita e eu gravamos uma série semanal de podcasts com as novidades da semana no mundo do Ruby e Rails.
Para comemorar esta data especial, eu montei uma lista com os 10 artigos mais lidos nestes três anos.
Os 10 mais lidos
- New Free Book: “Ruby on Rails 2.1 – What’s new”
- Shoulda for RSpec is Remarkable!
- O primeiro livro sobre Rails 2.1 é brasileiro!
- Como Ruby on Rails pode o tornar um programador pior
- Ruby on Rails 2.1 What’s New – Second Edition
- Como motivar um programador
- Adicione algo de valor ao universo
- Livro Grátis: Ruby on Rails 2.2 – O que há de novo?
- Os oito níveis do programador
- Free Book: Ruby on Rails 2.1 – What’s New (7 translations)
Além desses artigos eu gostaria de listar outros que considero importantes na história do blog:
- Um presente para a comunidade de desenvolvedores brasileiros de Ruby e Rails
- Programar é difícil
- Os screencasts perdidos do Nome do Jogo
- Isto é um bug no Javascript?
- O (comovente) guia de Ruby do Why
- Autotest Notification – Doom Edition
- Rails Podcast Brasil #1
Eu agradeço a todos os leitores, principalmente aqueles que comentam e compartilham os artigos no Twitter, você são o combustível para que eu continue pesquisando e escrevendo.
Rails 3.0 é como pôneis e arco-íris! Ele irá fazer o seu jantar e dobrar a sua roupa. Vocês irão se perguntar como era possível viver antes disso. É a melhor versão do Rails que nós já fizemos!
Agora é sério, isso é algo realmente bom. Todas as boas ideias que a equipe do Merb trouxeram desde que se juntaram ao projeto estão lá, isso inclui um foco mais agnóstico ao framework, um código mais magro e rápido e um monte de saborosas APIs. Se você está vindo para o Rails 3.0 a partir do Merb 1.x, você deve reconhecer várias dessas APIs. Se você está vindo do Rails 2.x, você vai adorar isso também.
Mesmo se você não der a mínima para nenhuma das nossas limpezas internas, o Rails 3.0 também estará nas suas graças. Temos um monte de novos recursos e APIs melhoradas. Nunca houve uma época melhor para ser um desenvolvedor Rails.
É interessante analisar o efeito que uma linguagem de programação tem sobre a mente do programador, principalmente a sua capacidade de influenciar a maneira como enxergamos um problema. A diferença na sintaxe e os recursos disponíveis afetam a forma como pensamos e nos comunicamos, inclusive no mundo real.
O mesmo problema pode ser solucionado de várias formas diferentes, dependendo da linguagem de programação adotada. Certamente a abordagem escolhida para resolver um problema utilizando Ruby não será a mesma se você usar Java.
Outro fator que exerce uma grande influencia sobre a forma como resolvemos os problemas e pensamos é o domínio do aplicativo. Somos tentados a utilizar o mesmo vocabulário do cliente no código. O meu conselho é tirar o máximo de vantagem desse efeito. Pode ser realmente produtivo “falar” a mesma língua que o cliente também dentro do código. Por exemplo, se o cliente explicar uma funcionalidade dessa maneira:
Quando todas as unidade de um produto se esgotarem em uma das lojas, então o sistema deve solicitar mais 10 unidades do mesmo produto para a fábrica.
Seria muito bom se o código produzido fosse algo parecido com isso:
if product.sold_out?
Factory.order 10, product, :to => store
end
É óbvio que não esperamos que o cliente entenda o código e muito menos que ele altere algo por conta própria, mas nós programadores podemos nos beneficiar muito disso.
Não importa se você está escrevendo um código simples como o exemplo acima ou se construiu uma DSL para se aproximar ainda mais da linguagem do cliente. O importante é estreitar a comunicação entre os envolvidos. Assim o seu cérebro estará livre para se concentrar no que realmente interessa: a solução de problemas.
Já faz um tempo que eu tenho planejado traduzir essa excelente entrevista de Bill Venners com Yukihiro Matsumoto. Finalmente conseguir finalizar a primeira parte.
Yukihiro Matsumoto, ou “Matz” como ele é conhecido online, é o criador da linguagem de programação Ruby. Ruby é uma linguagem orientada a objetos adequada tanto para a escrita de scripts do dia a dia como de aplicativos de larga escala. Matz começou a trabalhar no Ruby em 1993, porque queria uma linguagem que o tornasse mais produtivo ao mesmo tempo que fosse divertida de usar. Embora inicialmente tenha se tornado mais popular no Japão, Ruby tem conquistado programadores no mundo todo.
Em 24 de setembro de 2003, Bill Venners se encontrou com Yukihiro Matsumoto na conferência JAOO em Aarhus, na Dinamarca. Nesta entrevista, que foi publicada em várias partes no site Artima.com, Yukihiro Matsumoto discute a filosofia por trás da arquitetura do Ruby, as características da linguagem e como tornar-se um programador melhor. Neste capítulo inicial, Matz filosofa sobre a imperfeição no design, o perigo da ortogonalidade, a concessão de liberdade com regras, o princípio da menor surpresa e a importância do ser humano no trabalho da máquina.
Não existe uma linguagem perfeita
Bill Venners: Dave Thomas, co-autor do livro “Programming Ruby: A Pragmatic Programmer’s Guide” me disse que você não acredita que uma linguagem de programação possa deve ser perfeita. Por que não?
Yukihiro Matsumoto: Desenvolvedores querem criar a linguagem de programação perfeita. Eles querem poder dizer: “Veja, a minha linguagem é perfeita. Com ela você pode fazer qualquer coisa”. Mas é simplesmente impossível conceber uma linguagem perfeita, porque existem duas maneiras de se olhar para uma linguagem de programação. Uma maneira é olhar para o que pode ser feito com essa linguagem. A outra é observar como nos sentimos usando essa linguagem – como nos sentimos durante o tempo que estamos programando.
De acordo com a teoria da completude de Turing, tudo que uma linguagem Turing-complete pode fazer teoricamente pode ser feito por qualquer outra linguagem Turing-complete, mas de um jeito diferente. Você pode fazer tudo em Assembler, mas ninguém quer programar em Assembler. Do ponto de vista do que você pode fazer, entretanto, as linguagens diferem entre si – mas as diferenças são limitadas. Por exemplo, Python e Ruby fornecem quase o mesmo poder para o programador.
Em vez de enfatizar o “o que”, eu quero enfatizar o “como”: Como nos sentimos durante a programação. Essa é a principal diferença da arquitetura do Ruby em relação as outras linguagens. Enfatizo a sensação em “como” eu me sinto usando Ruby. Eu não trabalho para tornar o Ruby perfeito para todos, porque você tem sentimentos diferentes dos meus. Nenhuma linguagem pode ser perfeita para todos. Eu tentei fazer Ruby perfeito para mim, mas talvez ele não seja perfeito para você. A linguagem perfeita para Guido van Rossum é provavelmente o Python.
Ortogonal vs Harmonioso
Bill Venners: Dave Thomas alegou também que se eu pedir para você adicionar ao Ruby um recurso que é ortogonal, você não vai fazê-lo. O que você quer é algo que seja harmonioso. O que isto significa?
Yukihiro Matsumoto: Eu acredito que a coerência e a ortogonalidade são ferramentas de design, não o objetivo principal do projeto.
Bill Venners: O que significa ortogonalidade neste contexto?
Yukihiro Matsumoto: Um exemplo de ortogonalidade é adicionar qualquer recursinho ou sintaxe à linguagem. Por exemplo, C++ suporta parâmetros com valores padrão e também sobrecarga de funções com base em parâmetros. Ambos os recursos são bons para se ter em uma linguagem, mas devido ao fato desses recursos serem ortogonais, você pode aplicar ambos ao mesmo tempo. O compilador sabe exatamente o que fazer nesse caso. Se houver ambigüidade, o compilador irá sinalizar um erro. Mas se eu olhar para o código, vou precisar aplicar a regra com o meu cérebro. Eu preciso adivinhar como funciona o compilador. Se eu estiver correto, e for inteligente o suficiente, isto não será nenhum problema. Mas se eu não for inteligente o suficiente, e eu realmente não sou, isto causará muita confusão. O resultado será inesperado para uma pessoa comum. Este é um exemplo de como ortogonalidade pode ser ruim.
Bill Venners: Em outras palavras, as características ortogonais irão funcionar, uma vez que o compilador as entende e executa o programa. Mas é difícil para um programador compreender o funcionamento quando está olhando para o código, porque ele precisa descobrir como essas duas coisas funcionam juntas.
Yukihiro Matsumoto: Características ortogonais, quando combinadas, podem explodir em complexidade.
Bill Venners: Qual é a alternativa? O que seria mais harmonioso?
Yukihiro Matsumoto: Basta escolher uma das duas funcionalidade para colocar na linguagem. Você não precisa fazer tudo o que vier a sua cabeça. Você deve escolher apenas um desses recursos, mesmo que ambos sejam bons.
Liberdade e conforto
Bill Venners: Uma das filosofias da comunidade Python é fornecer uma e apenas uma maneira de fazer as coisas. Se você fornecer cinqüenta maneiras diferentes de fazer a mesma coisa, então você está fornecendo conveniências para quem está escrevendo o código. Cada programador terá a liberdade de escrever do jeito que preferir. Mas o problema não é com quem escreve, mas com a pessoa que está lendo o código. Você pode adotar uma forma de escrever o seu código e o programador do lado pode adotar uma outra forma. Assim, quem está lendo precisa estar familiarizado com todos as maneiras possíveis de se realizar aquela tarefa, não apenas a sua maneira favorita de codificar. Esse é o dilema do design. A comunidade Python parece preferir uma única abordagem, mas Ruby parece oferecer várias maneiras de se fazer a mesma coisa.
Yukihiro Matsumoto: Ruby herdou a filosofia do Perl de ter mais de uma maneira de fazer a mesma coisa. Eu herdei essa filosofia de Larry Wall, que é o meu herói atualmente. Eu quero que os programadores Ruby sejam livres. Eu quero dar-lhes a liberdade de escolher. As pessoas são diferentes. As pessoas tem diferentes critérios. Mas se há uma maneira melhor entre as várias alternativas, quero encoraja-la, tornando-a mais confortável. Então é isso que eu tentei fazer. Talvez um código Python seja um pouco mais legível. Qualquer um pode escrever utilizando o mesmo estilo em Python com a finalidade de deixar o código mais fácil de ler, talvez. Mas a diferença de uma pessoa para outra é tão grande, que prover apenas um caminho é de pouca ajuda mesmo se você estiver usando Python, eu acho. Eu prefiro dar tantas maneiras quanto for possível, mas incentivar ou orientar os usuários a escolher a melhor maneira, se ela existir.
Alegria
Bill Venners: Em um artigo introdutório sobre Ruby, você escreveu: “Para mim, o propósito da vida é, em parte, ter alegria. Programadores geralmente se sentem felizes quando podem concentrar-se na parte criativa da programação, assim Ruby foi projetado para fazer programadores felizes.” Como pode o Ruby fazer programadores felizes?
Yukihiro Matsumoto: Você quer aproveitar a vida, não é? Se você pudesse terminar seu trabalho rapidamente e de uma forma divertida, seria muito bom, não é? Esse é o propósito da vida, em parte. Sua vida será melhor.
Eu quero resolver os problemas que encontro no cotidiano usando computadores, então preciso escrever programas para eles. Usando Ruby, quero me concentrar nas coisas que faço, não nas regras mágicas da linguagem, como começar com um public something something void something para imprimir na tela: “Olá mundo”. Eu só quero dizer print "this!". Eu não quero todas estas palavras-chave envoltas em magia. Eu só quero me concentrar na tarefa. Essa é a idéia básica. Então, eu tenho tentado fazer um código Ruby conciso e sucinto.
Bill Venners: Permitir que os programadores escrevam código que é conciso e sucinto é uma maneira de fazê-los felizes.
Yukihiro Matsumoto: Sim, para que eles possam se concentrar no problema. As vezes as pessoas anotam pseudo-código em uma folha de papel. Se esse pseudo-código pudesse ser executado diretamente em seus computadores, seria muito bom, não seria? Ruby tenta ser assim, como esse pseudo-código sendo executado. O pessoal do Python também diz o mesmo.
Bill Venners: Sim, o pessoal do Python diz que o Python é um pseudo-código executável. O que mais tem no Ruby que faz os programadores felizes?
Yukihiro Matsumoto: No nosso cotidiano como programadores, processamos muito texto. Então, eu tentei trabalhar duro em processamento de textos, ou seja, na classe string e expressões regulares. As expressões regulares são incorporadas a linguagem e estão prontas para o uso. Também precisamos interagir muito com o sistema operacional. Ruby pode executar chamadas ao sistema Unix e para a maioria das funções da API do Windows. Isso aumenta o poder e a utilizade do sistema operacional no ambiente da linguagem interpretativa. Então você pode fazer a administração de sistemas e a programação diária de processamento de textos. É isso que faço na maior parte do tempo, então eu trabalhei duro em fazer isto funcionar bem.
Bill Venners: Então, basicamente, Ruby me permite aproveitar mais a minha vida, porque faz com que eu termine o meu trabalho mais rápido ao mesmo tempo que o torna mais divertido?
Yukihiro Matsumoto: Ele me ajuda a fazer isso. Não tenho certeza se Ruby funciona para você, mas eu espero que sim.
O Fator Humano
Bill Venners: Em uma entrevista, você disse: “Não subestime o fator humano. Embora estejamos em frente a um computador, eles são apenas máquinas. Estamos trabalhando para humanos, com humanos.” O que você quer dizer com isso?
Yukihiro Matsumoto: Imagine que você está escrevendo um e-mail. Está na frente do computador. Está operando o computador, clicando em um mouse e digitando em um teclado, mas a mensagem será enviada a um outro ser humano através da internet. Então você está trabalhando com um computador, mas o objetivo é sempre um ser humano. A maioria das tarefas que fazemos são para seres humanos. Por exemplo, um cálculo de impostos é a contagem de números que indicam quanto o governo pode retirar de dinheiro da minha carteira, mas o governo é composto por seres humanos.
A maioria de nossas tarefas estão relacionadas com seres humanos. Assim, quando programamos podemos tanto pedir ao computador para trabalhar para um ser humano, como podemos descrever nossos pensamentos de uma forma tão clara que até mesmo uma máquina possa executar. No primeiro caso, fazemos o computador trabalhar para o ser humano, o alvo é um ser humano atrás de um computador. No segundo caso, expressamos nossos pensamentos com clareza suficiente para ser compreendido e executado por computadores, a intenção é expressa por cérebros humanos e o resultado é calculado por um computador. Assim, em ambos os casos, o objetivo aqui é sempre o ser humano.
Bill Venners: O que é mais importante sobre este tipo de mentalidade? Você diz: “Não subestime o fator humano.” Por quê?
Yukihiro Matsumoto: Computadores não se importam se eu estou fazendo algum esforço para me comunicar com eles ou se é fácil de se comunicar com eles. Eles não se importam se eu coloquei uma seqüência de instruções em um arquivo e mandei executá-las ou se eu estou utilizando uma linguagem de alto nível para gerar essas instruções. Computadores não se importam. Nós nos preocupamos com os seres humanos. Muitas vezes as pessoas, especialmente engenheiros de informática, focam nas máquinas. Eles pensam: “Ao fazer isso, a máquina irá trabalhar mais rápido. Ao fazer isso, a máquina irá funcionar mais eficazmente. Ao fazer isso, a máquina irá fazer alguma coisa qualquer”. Eles estão se concentrando em máquinas. Mas, na verdade precisamos nos concentrar no ser humano, sobre como os seres humanos se preocupam com a programação ou como operam um aplicativo na máquina. Nós somos os mestres. As máquinas são nossos escravos.
Bill Venners: Pelo menos por enquanto.
Yukihiro Matsumoto: Pelo menos por enquanto, até chegarmos na era dos Exterminadores.
O princípio da menor surpresa
Bill Venners: Em uma entrevista, você disse “eu projetei o Ruby para minimizar a minha surpresa. Fiquei muito espantado quando as pessoas ao redor do mundo me disseram que Ruby reduzia a sua surpresa e aumentava a sua alegria ao programar. Agora eu tenho certeza que programadores pensam da mesma maneira no mundo todo.” Por que o principio da menor surpresa?
Yukihiro Matsumoto: Na verdade, eu não fiz a alegação de que Ruby segue o princípio da “menor surpresa”. Alguém sentiu que o design do Ruby segue esta filosofia, então eles começaram a dizer isso. Não foi eu quem inventou isto, na verdade.
Eu queria minimizar minha frustração durante a programação, assim como eu quero minimizar o meu esforço na programação. Esse era o meu principal objetivo na elaboração de Ruby. Eu queria me divertir enquanto programava. Depois de lançar o Ruby e muitas pessoas ao redor do mundo tomarem conhecimento da linguagem, eles começaram a dizer que se sentiam assim como eu me sinto. Eles começaram a citar esta frase sobre o princípio da menor surpresa. Mas, na verdade, isto é muitas vezes mal interpretado.
Bill Venners: Como isto é mal interpretado?
Yukihiro Matsumoto: Cada um possui um passado único. Alguns podem vir do Python, outros podem vir de Perl, e podem ser surpreendidos por diferentes aspectos da linguagem. Então, eles vêm até mim e dizem: “Fiquei surpreso com esta característica da linguagem, assim o Ruby viola o princípio da menor surpresa”. Espere. Espere. Esse princípio não vale apenas para você. O princípio da menor surpresa, também é o principio da minha menor surpresa. Mesmo programadores experientes podem ser surpreendidos. Por exemplo, eu era um programador C++ antes de começar a projetar o Ruby. Eu programei em C++ exclusivamente por dois ou três anos. E após todo este tempo programando em C++, eu ainda me surpreendia.
Atualização (20/01/2010 13:05):
Depois de publicar esse artigo descobri que o Fábio Akita já havia traduzido essa entrevista a alguns anos atrás. Assim, seguem os links para a parte 2, parte 3 e parte 4 da entrevista. Divirta-se!
Você sabe explicar a diferença entre as duas linhas abaixo?
load "my_library.rb"
Se você já trabalhou ao menos um pouco com Ruby, então sabe que load é útil quando se deseja executar o código de um arquivo enquanto require é utilizado para importar uma biblioteca para dentro do código do seu programa.
Esta definição está correta, mas eu gostaria de me aprofundar um pouco mais no assunto…
A Base
Para entender como esses métodos realmente funcionam por dentro, precisamos primeiro saber que ambos possuem a mesma base. No Ruby 1.8.7 esta base é o método rb_load (internamente escrito em C e encontrado no arquivo eval.c). A função do rb_load é determinar se o arquivo especificado na chamada dos métodos require e load se encontra no diretório atual do aplicativo ou em um dos diretórios listados no $LOAD_PATH ($:) e então carregar este arquivo seguindo a regra própria de cada um dos métodos.
O método require por dentro
Quanto rb_load é executado através do método require, fazendo com que ele carregue uma biblioteca no seu código, o nome do arquivo especificado é adicionado a uma lista. Esta lista pode ser vista através da variável global $LOADED_FEATURES ($").
Você pode verificar quais arquivos já foram carregados em seu código através do método require analisando o conteúdo desta variável.
[carlosbrando:~]$ irb
>> puts $LOADED_FEATURES
enumerator.so
e2mmap.rb
irb/init.rb
...
Ao executar o método require, o Ruby primeiro verificará se o nome do arquivo que você especificou se encontra em $LOADED_FEATURES. Se ele não encontrar o nome na lista, então ele tentará carregar o arquivo e se for bem sucedido retornará true. Caso o nome já se encontre na lista de recursos carregados, então o método simplesmente retornará false e não carregará o arquivo novamente.
O segundo passo é determinar em que diretório o arquivo se encontra. Para isto o Ruby consultará uma outra variável global chamada $LOAD_PATH. Esta variável armazena todos os diretórios onde rb_load deve procurar por bibliotecas. Se o arquivo não for encontrado no diretório raiz do seu aplicativo e nem na lista de diretórios do $LOAD_PATH, então o método rb_load disparará um erro do tipo LoadError.
Caso você não informe uma extensão para o nome do arquivo, como no exemplo no inicio deste tópico, o método require procurará por arquivos com as seguintes extensões: .rb, .o, .so, .dylib, .dll, exatamente nesta ordem. Por último o Ruby procurará pelo nome do arquivo sem nenhuma extensão. Se o arquivo possuir a extensão .rb ele será carregado como um código Ruby puro. As demais extensões serão carregadas como extensões Ruby de acordo com o sistema operacional na qual você estiver executando o seu código.
Atenção: Se você informar a extensão do arquivo na chamada do método require (i.e. require 'my_lib.rb') e o Ruby não conseguir encontrar o arquivo da forma como foi especificado, ele ignorará a extensão que você definiu e procurará por arquivos com o mesmo nome seguindo a regra mencionada no parágrafo anterior.
O método também permite que você seja mais especifico, informando o diretório exato onde o arquivo se encontra.
No exemplo acima o Ruby não tentará localizar o recurso em outros diretórios, caso não o encontre no local que você especificou. Porém, é importante estar atento a um problema comum ao utilizar este recurso. Veja o código abaixo:
Neste exemplo, nas duas linhas de código eu estou carregando o mesmo recurso. Na primeira linha eu informo somente o nome do arquivo e na segunda eu informo também o diretório. O método require não armazena o caminho absoluto do recurso em $LOADED_FEATURES, ele armazena a string exata informada na chamada do método. Neste caso o arquivo my_library.rb será carregado duas vezes. Analisando a variável $LOADED_FEATURES encontraremos o seguinte:
>> $".grep /my_library/
=> ["my_library.rb", "./my_library.rb"]
O método load por dentro
O método load funciona de uma forma muito parecida com o método require. A principal diferença é que ele não mantém uma lista de recursos, fazendo com que um arquivo seja carregado tantas vezes quanto for solicitado.
Outra importante diferença é que a extensão do arquivo é obrigatória, embora ela não seja restrita apenas a .rb e aos outros formatos que vimos acima. Qualquer outra extensão é aceita, embora o conteúdo do arquivo seja sempre tratado como código Ruby puro.
Você também pode especificar o caminho exato onde o arquivo se encontra. Desta vez, sem nenhum efeito colateral. Porém, se você informar somente o nome do arquivo, o Ruby tentará encontrá-lo primeiro no seu diretório atual e depois na lista de diretórios do $LOAD_PATH.
O método load tem algumas opções extras. Muito provavelmente o arquivo que você estará carregando definirá algumas variáveis e classes. Variáveis locais em nenhuma circunstancia serão propagadas para o seu ambiente, porém o mesmo não acontece com constantes. O resultado é que ao carregar um recurso em seu projeto você pode ter um conflito se já houver uma constante com o mesmo nome no seu código. O mesmo vale para nomes de classes, que como já aprendemos também são constantes.
Você pode obrigar o método load a manter suas constantes para si mesmo, passando um segundo parametro na chamada do método:
load 'my_library.rb', true
Quando você carrega um recurso desta maneira, o Ruby criará um módulo anônimo e usará este módulo como um namespace, evitando conflitos entre o código do arquivo e o seu código. Ao terminar a execução este módulo é destruído. No exemplo acima, true é um atalho. Se desejar, você pode ser mais especifico fazendo também desta maneira:
load "my_library.rb", :wrap => true
O efeito é o mesmo.
Finalizando
O método require não tem opções extras. Se você está importando uma biblioteca então faz sentido que constantes e classes permaneçam em seu código. Por outro lado, se você deseja apenas executar o código que está em um arquivo, provavelmente você não vai querer poluir o seu programa com recursos desnecessários.
Os dois métodos são muito parecidos, embora eles tenham sido construídos para finalidades diferentes. Entender como cada um funciona por dentro pode ajudá-lo a utilizar o recurso certo na hora certa.
O ano começou muito bem para os leitores deste blog. No finalzinho de 2008, logo após o lançamento do Rails 2.2, eu havia publicado em parceria com o site EnvyCasts, o meu segundo livro em um pacote especial com um screencast produzido por Gregg Pollack e Jason Seifer. No primeiro mês do ano eu disponibilizei a versão em português do livro de graça aqui no site.
Fevereiro foi outro mês muito exitante. Depois de meses de negociação, consegui com a ajuda de Peter Cooper, trazer o famoso site Ruby Inside para o Brasil. A comunidade Ruby nacional ganhou uma excelente fonte de informações sobre tudo o que acontece de novo no mundo sobre Ruby e Rails. Além de traduzir a maior parte dos artigos publicados na versão internacional, também publicamos muitos artigos relevantes para o público de língua portuguesa e distribuímos muitos prêmios durante o ano.
Dois artigos se destacaram no mês de março: Don’t Repeat Yourself e Um pouco mais sobre “Don’t Repeat Yourself”.
Depois de aproximadamente um ano de trabalho duro, finalmente em abril de 2009 finalizamos a tradução do livro “O (comovente) guia de Ruby do Why“. Foi um trabalho colossal realizado por muitos membros da comunidade Ruby brasileira. Também foi neste mês que aconteceu o evento Ruby + Rails no mundo Real 2009, organizado pelo Guru-SP. A galera do Ruby Inside Brasil esteve em peso no evento e realizou uma excelente cobertura. Eu fui um dos palestrantes, com o tema “Só imaturos não testam” (veja o vídeo). E ainda para fechar o mês com chave de ouro, depois de meses de trabalho eu e José Valim finalmente liberamos a versão 3.0 do framework Remarkable, com alguns recursos novos que tornaram o projeto a principal biblioteca de matchers para RSpec.
Embora o 14º EDTED tenha acontecido em abril, somente em maio tive acesso ao vídeo da palestra que realizei no evento. O tema desta vez foi “Como Ruby on Rails pode o tornar um programador pior“. Neste mês também tentei iniciar uma série de screencasts sobre curiosidades do Ruby, infelizmente o projeto não foi para frente.
Em junho, ainda empolgado com a gravação de screencasts criei um segundo site com a finalidade de agregar todos os vídeos relacionados a Ruby e Rails, como screencasts e gravações de palestras. O site ainda está no ar, embora eu não tenha dado prosseguimento ao projeto (Se alguém se interessar em tocar o projeto, fale comigo). Também foi neste mês que escrevi o artigo mais lido do ano: “Como motivar um programador“.
Um dos destaques de julho foi o artigo “Não tenho tempo para conquistar meus sonhos“.
Agosto marcou o inicio da temporada de eventos sobre Rails. O primeiro foi o Oxente Rails, um mega evento organizado pelo meu amigo Paulo Fagiani. Infelizmente as gravações das palestras ainda não foram disponibilizadas. Ainda neste mês, escrevi um artigo intitulado “Isto é um bug no Javascript?“, que foi bastante comentado.
Outro importante evento aconteceu em setembro, o Rails for Kids. O tema da minha palestra desta vez foi “Eu odeio OpenSocial“, uma introdução ao tema da palestra que eu iria realizar no Rails Summit. Um artigo que se destacou neste mês foi uma tradução entitulada “Os oito níveis do programador“.
Outubro foi um mês cheio de emoções para mim. Primeiro eu oficializei a minha saída da Surgeworks e o inicio de um novo desafio, atuar como diretor de tecnologia na Amanaiê (SocialSmart), uma startup brasileira. E também foi neste mês que aconteceu o evento mais esperado do ano, o Rails Summit Latin America, organizado pela Locaweb e encabeçado pelo meu amigo Fábio Akita. Este ano tive o privilégio de palestrar mais uma vez neste evento, você pode assistir o vídeo clicando aqui.
Novembro e dezembro foram meses de muito trabalho na Amanaiê, onde estou tendo o privilégio de construir um novo framework em Ruby para acelerar o desenvolvimento de aplicativos baseados em OpenSocial. Já temos alguns projetos no ar utilizando a nova tecnologia e estamos muito animados com os resultados.
Enfim, 2009 foi mais um ano de muitas conquistas e muito trabalho. Agora chegou a hora de um merecido descanso. Nos vemos em 2010!
Qual é a diferença entre uma classe e um módulo no Ruby? Nenhuma, uma classe é um módulo no Ruby. Não acredita em mim?
Class.is_a?(Module) # => true
Agora que você já confia em mim, posso explicar com um pouco mais de calma.
O que são módulos?
Um módulo pode ser definido de forma grosseira como uma coleção de métodos e constantes. Você encontrará dois tipos de métodos em um módulo: métodos de instância e métodos de módulo. Um método de módulo é aquele que pode ser executado sem a necessidade de que o módulo seja incluído em outro objeto:
puts "Sou um método de módulo!"
end
end
MeuModulo.meu_metodo_de_modulo # => Sou um método de módulo!
Por outro lado, métodos de instância, como o nome diz, precisam ser executados a partir de uma instância de um objeto. Módulos podem ser acoplados dentro de outros objetos, tornando assim estes métodos de instância acessíveis.
puts "Método de instância!"
end
end
# Acoplando o MeuModulo
include MeuModulo
end
# Criando uma instância de MinhaClasse
minha_classe = MinhaClasse.new
# Executando o método de instância que foi criado em MeuModulo
puts minha_classe.meu_metodo_de_intancia # => Método de instância!
O que são classes?
Assim como os módulos, classes também são repositórios de métodos. Então qual é a diferença entre um e o outro?
Podemos ver claramente a diferença entre classes e módulos examinando o objeto Class mais de perto:
Class.superclass # => Module
Class.instance_methods(false)
# => ["superclass", "allocate", "new", "to_yaml"]
Como você pode ver no código acima, Class é uma subclasse de Module, mas com quatro métodos a mais. E é exatamente nestes métodos que encontraremos a resposta para a questão levantada acima.
Para esclarecer ainda mais, vamos imaginar como seria a classe Class implementada em Ruby:
# Você já sabe como funciona o método new,
# já que o utilizamos o tempo todo
end
# Devolve a superclasse da classe atual
end
# Dá suporte ao método new
end
end
end
Os três primeiros métodos são responsáveis por permitir que você consiga criar uma instância de um objeto e trabalhar com o conceito de hierarquia de classes. O método to_yaml serve apenas como uma interface que dispara um erro do tipo TypeError caso ele não seja implementado por uma subclasse.
O método superclass é fácil de entender, já que a sua única finalidade é informar qual é a superclasse de um objeto. Se uma superclasse não for definida ele retornará nil.
Integer.superclass # => Numeric
Object.superclass # => nil
O método allocate é responsável por reservar um espaço na memória para a nova instância do objeto que estamos criando. O método devolve esta instância pronta.
E por último, o método initialize (new) tem duas funções. Primeiro ele executa o método allocate, que constrói um novo objeto da classe Class (ou de qualquer outra classe, afinal todas elas são subclasses de Class). Em seguida ele dispara o método initialize deste objeto, passando os argumentos para ele.
Finalizando
Se você chegou até aqui, então já entendeu as diferenças entre um módulo e uma classe em Ruby. Basta pensar que ambos são basicamente a mesma coisa (com estas significantes diferenças) e que quase tudo o que vale para um também vale para o outro.
A principal razão de existir estes dois tipos de objetos tão parecidos e ao mesmo tempo tão diferentes é que desta forma podemos deixar nosso código muito mais expressivo.
Normalmente você usará um módulo quando precisar incluí-lo em outro objeto ou usá-lo como um namespace. E você usará uma classe quando precisar de uma instância de um objeto ou utilizar o sistema de heranças. Cada um tem o seu propósito e você será melhor sucedido se utilizar o recurso certo na hora certa.
Este artigo é o primeiro de muitos com a finalidade de explicar como o Ruby e Rails funcionam por dentro, conforme prometido durante a minha palestra no Rails Summit.
A Locaweb disponibilizou através do seu portal no Vimeo os vídeos das palestras no Rails Summit 2009. No total são 13 vídeos, o suficiente para você se manter ocupado por todo o feriado.
Abaixo você pode ver a gravação da minha palestra no evento. A ideia geral é mostrar que Ruby on Rails embora tenha uma influência muito forte, não deixa de ser apenas “mais um framework Ruby”. Isto deve nos motivar a também buscar outras alternativas, ou até mesmo criar novos frameworks, quando Rails não mostrar ser a melhor opção para o desenvolvimento de um projeto.
Você também pode encontrar outras apresentações na minha página de palestras.
Como a maioria deve saber, um dos grandes diferenciais do Rails vem de uma característica que também é marcante em seu criador. Ruby on Rails é um software de opinião. Atualmente DHH não é mais tão ativo no desenvolvimento do Ruby on Rails quanto no passado. Porém de tempos em tempos ele aparece com algumas inclusões polêmicas no framework.
Seu último patch é referente a inclusão das opções :alert, :notice e :flash no método redirect_to. Assim, se antes fazíamos desta maneira:
flash[:notice] = 'Post was created'
redirect_to(@post)
Agora podemos fazer assim:
redirect_to(@post, :notice => 'Post was created')
Esse sem dúvida é um recurso interessante e nos ajudará a diminuir a quantidade de linhas de código que escrevemos. Porém alguns desenvolvedores não gostaram desta implementação argumentando que não costumam utilizar flash[:alert] como sinalizador de problemas, mas sim flash[:error].
A resposta de DHH? “Nós estamos utilizando alert para tudo na 37signals. Isto realmente não importa. Só que exista um sinalizador para continuar e outro para parar”.
Aceitando ou não esta explicação é importante lembrar do fato de que desde o principio foram estas “convenções” que tornaram o Rails o que ele é hoje. Sendo assim, a melhor coisa a fazer é passar a adotar o padrão definido.
Outros exemplos extraídos da documentação:
redirect_to post_url(@post), :alert => "Watch it, mister!"
redirect_to post_url(@post), :status=> :found,
:notice => "Pay attention to the road"
redirect_to post_url(@post), :status => 301,
:flash => {:updated_post_id => @post.id }
redirect_to {:action=>'atom' }, :alert => "Something serious happened"
[Atualização 18/12/2009 18:20]
Uma informação importante é que existe uma boa chance deste novo recurso entrar em algum futuro release do Rails ainda na versão 2.3.x.
Além disso, também esqueci de mencionar que foram criados métodos mais convenientes para facilitar o acesso ao flash[:notice] e flash[:alert]. Podemos acessar estes recursos simplesmente assim:
Muitas novidades estão sendo preparadas para a próxima versão do Rails. Uma que já estamos observando a alguns dias é a nova DSL para a configuração de rotas.
O Rails 3 ainda está em desenvolvimento, isto significa que o código da DSL pode sofrer alterações até o lançamento oficial. De qualquer forma você pode ir matando a curiosidade analisando o novo arquivo config/routes.rb que está sendo gerado pelo Rails 3.0.pre neste momento. Eu tomei a liberdade de traduzir os comentários para facilitar o entendimento.
ActionController::Routing::Routes.draw do |map|
# A prioridade é baseada na ordem da criação:
# criado primeiro -> maior prioridade.
# Exemplo de uma rota comum:
match 'products/:id', :to => 'catalog#view'
# Tenha em mente que você pode atribuir outros valores além de
# :controller e :action
# Exemplo de uma rota nomeada:
match 'products/:id/purchase',
:to => 'catalog#purchase', :as => :purchase
# Esta rota pode ser invocada utilizando
# purchase_url(:id => product.id)
# Exemplo utilizando resources (mapeia verbos HTTP para ações do
# controller automaticamente)
resources :products
# Exemplo utilizando resources com opções:
resources :products do
member do
get :short
post :toggle
end
collection do
get :sold
end
end
# Exemplo utilizando resource com sub-resources:
resources :products do
resources :comments, :sales
resource :seller
end
# Exemplo mais complexo de uso de resources com sub-resources:
resources :products do
resources :comments
resources :sales do
get :recent, :on => :collection
end
end
# Exeplo utilizando resource com um namespace:
namespace :admin do
# Direciona /admin/products/* para Admin::ProductsController
# (app/controllers/admin/products_controller.rb)
resources :products
end
# Você pode definir a home do seu site utilizando "root"
# Lembre-se de apagar o arquivo public/index.html.
root :to => "welcome"
# Você pode listar todas as rotas disponíveis com "rake routes"
# Deixe a rota padrão com a prioridade mais baixa possível.
# Nota: A rota padrão torna todas as actions em qualquer controller
# acessíveis via solicitações GET. Você deve considerar a remoção
# ou comentar esta linha se estiver usando rotas nomeadas e recursos.
match ':controller(/:action(/:id(.:format)))'
end
[ATUALIZAÇÃO 21/12/2009 3:00]
A DSL sofreu uma leve alteração que simplifica ainda mais a especificação de rotas.
# As duas linhas a seguir fazem a mesma coisa
match 'products/:id', :to => 'catalog#view'
match 'products/:id' => 'catalog#view'





