Se você está preocupado com a performance do seu programa, saiba que métodos macarrônicos são mais velozes. Ao escrever todo o código dentro de um único método você estará evitando todos os custos envolvidos na chamada de outros métodos, reduzindo o tempo de execução do seu código.
Embora o argumento acima não seja falso, é triste reconhecer que muitos programadores ainda possuem esse tipo de pensamento. Talvez não de uma forma tão radical, mas são poucos os profissionais que entendem que programar é muito mais do que escrever instruções para um computador, mas que o código que escrevemos também será lido por outras pessoas.
O tamanho do método é proporcional a dificuldade de manutenção e entendimento. Quando damos prioridade a escrever métodos pequenos e com nomes descritivos aumentamos a produtividade do time (incluindo o autor do código).
Métodos pequenos, com poucas linhas de código, facilitam a manutenção e a inserção de novas funcionalidades. Use as características da linguagem a seu favor. Não é feio criar um método com um nome longo e descritivo em Ruby. Respeite a pontuação. Acrescente o sinal de interrogação no final quando o método retornar um booleano.
Não estamos apenas escrevendo código, estamos nos comunicando.
P.S.: Sim, eu acabei de ver uma coisa que me deixou irritado.
Definir quanto tempo será necessário para finalizar uma tarefa ou o desenvolvimento de um software não é (ou pelo menos não deveria ser) algo trivial. Estimar prazos faz parte do nosso dia-a-dia como programadores.
O que muita gente não se dá conta é que a precisão com que um programador prevê a entrega de tarefas e projetos é um poderoso indicador do quão bom ele é.
Para informar de forma precisa o tempo necessário para a realização de algo em desenvolvimento de software é necessário que o programador possua uma certa experiência no assunto, tenha um bom domínio do negócio, seja rápido e produtivo.
Embora muitos de nós não apreciem essa difícil tarefa, estimar prazos é parte do nosso trabalho. Fazer isso bem pode ser a diferença entre um programador profissional e um amador.
Em um dia normal, estamos estimando prazos o tempo todo. Ao colocar a comida no micro-ondas você deve informar quantos minutos serão necessários para esquenta-la. Se você tem um horário fixo para acordar, deve analisar quantas horas de sono serão suficientes e então decidir quando deve ir para a cama.
O segredo não está no tempo, mas em quão precisa deve ser a sua estimativa. Se seu chefe pergunta que horas você entregará o relatório amanhã, ele quer ter uma ideia se será antes ou depois do almoço. Se ele lhe pergunta quanto tempo será necessário para resolver um bug critico e colocar o sistema de volta em produção ele precisa de uma precisão maior.
A escala de tempo é muito importante ao se estimar prazos. Por exemplo, você pode dizer “O projeto será entregue em 25 dias” ou pode dizer “O projeto será entregue em cerca de 5 semanas”. Embora ambas as frases indiquem o mesmo tempo, o efeito sob cada uma delas pode ser diferente. Ao dar a primeira resposta, seu cliente provavelmente anotará na agenda dele o dia exato em que você entregará o projeto. Por outro lado, a segunda resposta fará com que ele lhe procure a qualquer momento daqui a 4 ou 6 semanas.
O livro The Pragmatic Programmer dá uma importante dica que nos ajuda a escolher a escala de tempo apropriada ao estimar prazos. Veja a tabela:
1-15 dias -> dias
3-8 semanas -> semanas
8-30 semanas -> meses
30 + semanas -> pense bem antes de dar uma estimativa
Qual a vantagem disso? O fato é que quanto maior o tempo, mais difícil é a previsão, exigindo que você seja cada vez mais impreciso. Por exemplo, se sua estimativa é que serão necessários 125 dias para terminar um trabalho, é muito mais seguro dizer que precisará de “cerca de 6 meses” para finaliza-lo.
Todas as estimativas que fazemos são baseadas em nossas experiências passadas. Mas, o que fazer quando é necessário estimar algo que você nunca fez ou que não conhece? A resposta é simples: “não estime”. É melhor pedir para que alguém que já tenha feito algo semelhante lhe dê uma ideia do tempo necessário.
Além de considerar o grau de precisão, também é importante entender qual é o problema antes de começar a chutar um tempo. Quase sempre nossas estimativas dependem de outros fatores para darem certo: “Supondo que não haja trânsito dá para chegar aí em 20 minutos”.
Se possível é muito útil testar alguns aspectos do projeto antes de dizer quanto tempo será necessário para cumpri-lo. Se o sistema precisa ser carregado dentro do Facebook, seria muito bom poder gastar um tempo criando alguma coisa bem simples para esta plataforma afim de analisar o grau de complexidade, isto sem dúvida aumentará a precisão da estimativa.
É muito importante levar em consideração que a equipe, sua produtividade e o ambiente afetam diretamente sua estimativa.
Analisando todos estes fatores, a conclusão é que há apenas uma única resposta correta a se dar quando lhe é pedido para estimar um prazo: “Me dê algum tempo para pensar”. Você sempre terá resultados melhores se retardar a resposta e pensar um pouco mais.
Eu amo programadores incompetentes. Graças a eles os profissionais de TI não podem reclamar de falta de emprego.
Nos últimos anos o mercado nacional de TI registrou um aumento de 40% no número de novas vagas de trabalho. Há estimativas que revelam que a necessidade de programadores no Brasil ultrapassa 40 mil profissionais por ano.
Afim de resolver esse problema, as empresas tem contratado cada vez mais programadores ruins. Porém nós não temos um problema com a quantidade, mais sim com a qualidade. Apenas um único programador incompetente pode facilmente criar duas novas vagas de emprego por ano.
Contratar mais programadores ruins só aumentará a necessidade por mais deles. Se tivéssemos mais programadores bons (que são facilmente identificados), seria necessário contratar menos e não mais.
Assim, quanto mais programadores ruins no mercado, mais empregos. Vida longa aos programadores incompetentes!
Eu tenho uma lista de programadores que merecem o meu respeito. Provavelmente você também deve admirar o trabalho de alguns colegas de profissão. Estranhamente, eu sou obrigado a confessar que vi muito pouco do código de cada um deles.
A maior parte desses programadores ganharam o meu respeito através dos softwares ou livros que escreveram. E não através do seu código.
Um exemplo é Yukihiro Matsumoto. Ele foi o criador da linguagem de programação que utilizo diariamente para realizar o meu trabalho e obviamente está na minha lista de heróis, porém pouquíssimas vezes eu olhei para o código fonte do Ruby, e quando o fiz não teria como identificar se o que estava vendo foi originalmente escrito por Matz ou por algum outro colaborador.
Minha lista está recheada de pessoas que escreveram uma linguagem de programação interessante, um framework útil, uma ferramenta que facilita minha vida ou um bom livro sobre programação. Mas são poucos os que passei a admirar depois de ver algum código que escreveram. Isso me faz pensar…
Na realidade o código que escrevemos tem muito pouco impacto sobre as pessoas. O que realmente interessa é o que fazemos com o código. O que importa é o produto final.
O problema é que a maior parte dos programadores se preocupa demais com o código. Passam horas e mais horas tentando criar o algoritmo perfeito. Porém se esquecem que o melhor código do mundo é inútil se ninguém utilizar o software que o contém.
De forma alguma estou dizendo que devemos jogar tudo para o alto e parar de se importar com a qualidade do código que escrevemos. Porém, tão importante quanto realizar um bom trabalho é fazer com que outras pessoas tomem conhecimento do que você está fazendo. A minha proposta é que aqueles que já são bons programadores hoje, invistam em aperfeiçoar suas habilidades como escritores e palestrantes. Que participem mais ativamente nas comunidades de software e melhorem suas habilidades sociais.
São essas habilidades que vão diferencia-lo dos demais. Não escreva apenas código. Estude, escreva e fale mais sobre código.
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!









