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.
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.
Não é segredo para ninguém que eu estou exaustivamente trabalhando em um novo framework para o desenvolvimento de aplicativos sociais de forma ultra-rápida. Porém ainda não está na hora de liberar o projeto como open source, mas é certo que isto acontecerá em breve.
O framework já está em sua versão 0.5.2 e em pleno uso e desenvolvimento. Como decidimos não liberar o projeto até que ele esteja finalizado, não podemos simplesmente disponibilizar as gems em serviços como o Gemcutter. Assim, toda vez que precisamos instalar ou atualizar as bibliotecas em nossos servidores temos de fazer isto manualmente, copiando os arquivos .gem para o servidor e instalando a partir deles. Este processo é realmente irritante, então surgiu a necessidade de montar o no nosso próprio servidor de gems privativo.
A solução é ridiculamente simples. Mas como acredito que muita gente também pode se beneficiar disso, segue a receita de bolo.
A forma simples
A primeira alternativa é utilizar o seu próprio computador como um servidor de gems. Para fazer isto basta executar o seguinte comando no terminal:
gem server
Pronto! Desta maneira você já estará compartilhando todas a gems que estão instaladas em sua máquina através do endereço http://SEU_IP:8808.
Uma alternativa melhor
Como em nosso caso era importante manter o serviço o tempo todo no ar, a solução foi hospedar as bibliotecas em um servidor web.
O processo também é muito simples. Crie um diretório qualquer em uma área pública do seu servidor web (digamos que você criou um diretório com o nome de meusgems). Crie então um subdiretório chamado gems e copie todos os seus arquivos .gem para dentro dele.
Antes de continuar certifique-se de ter o RubyGems instalado em seu servidor. Então execute o seguinte comando dentro do diretório meusgems:
gem generate_index
Feito! Seu servidor privado de gems está no ar. Quando adicionar ou atualizar alguma biblioteca, basta executar o comando acima novamente.
Instalando gems a partir do seu servidor
Para fazer com que o comando gem install encontre as bibliotecas que estão no seu servidor, você deve adicionar o endereço na lista de fontes do RubyGems. Para isto execute o seguinte comando no computador onde os gems devem ser instalados:
gem sources --add http://gems.meu_servidor.com
Claro que você deve alterar o endereço acima para a URL correta do seu servidor. Depois disso basta instalar as suas bibliotecas normalmente, através do comando gem install nome_do_gem.
Caso seu repositório de gems comece a crescer muito, talvez seja interessante configurar o projeto Gemcutter em seu servidor.
Esta pode ser uma alternativa bem interessante para estimular a reutilização de código dentro de sua empresa, sem precisar liberar todas as suas bibliotecas como open source.
Recentemente eu precisei desenvolver um módulo de log para o framework no qual estou trabalhando e não sabia como recuperar quem havia disparado o método atual no momento do registro do log.
Depois de pesquisar um pouco encontrei a resposta, um método muito simples no Kernel do Ruby chamado caller que devolve um array com o call stack. O primeiro item do array é quem disparou o método atual. E cada elemento consecutivamente é aquele que disparou o método anterior na fila, e assim se segue até o final da pilha.
Este método pode ser muito útil quando se deseja descobrir a causa de uma exceção em um aplicativo. Veja um exemplo:
1 2 puts caller 3 end 4 5 6 metodo_a 7 end 8 9 metodo_b 10 11 # => ["untitled:6:in `metodo_b'", "untitled:9"]
Conforme você pôde ver no exemplo acima, o primeiro item no array informa que o metodo_a foi disparado pelo metodo_b na linha 6 e que o metodo_b foi disparado na linha 9.
O string de retorno sempre seguirá o formato [arquivo]:[linha] ou [arquivo]:[linha]: in [método].
Recentemente fiz a seguinte pergunta no Twitter:

@carlosbrando
As respostas que recebi apenas confirmaram o que eu já imaginava.

@tapajos

@flaviogranero
O motivo da pesquisa é que recentemente eu estava lendo um artigo onde o autor argumentava que o ideal seria criarmos classes somente com métodos públicos, evitando ao máximo métodos privados ou protegidos. E entre outros argumentos, um dos motivos para se fazer isto era simplificar a criação de testes.
Uma coisa que me preocupa no Ruby é que é muito comum encontrar programadores que não estão nem um pouco preocupados se os seus métodos são públicos, protegidos ou privados. Pior ainda, quando tomam decisões apoiando-se em argumentos como o acima.
Um clássico exemplo são os métodos de callback de validações do Active Record, que em praticamente 99% dos casos deveriam ser privados ou protegidos, mas é normal encontrá-los entre os métodos públicos de um modelo na maioria dos projetos Rails. Acredito que isto aconteça porque programadores iniciantes entusiasmados com as facilidades do Active Record apenas saem incluindo seus códigos sem pensar muito no que estão fazendo.
Eu também não tenho o hábito de testar métodos privados, pelas mesmas razões mencionadas pelos amigos do Twitter. Mas no Ruby, se você realmente desejar, é trivial realizar uma chamada em um método privado de um objeto. Uma das técnicas mais usadas por “testadores de métodos privados” é se valer das características dinâmicas da linguagem para transformar todos os métodos privados de uma classe em métodos públicos durante os testes. Diferente de outras linguagens, como C# por exemplo, onde você tem uma barreira formal para impedi-lo de acessar métodos privados, no Ruby é ridiculamente simples ultrapassar esta barreira.
Pensando desta maneira, definir um método como privado no Ruby pode não significar muita coisa, já que outro programador pode alterar esta característica com facilidade. Mas ainda assim, definir um método como privado é como dizer aos outros programadores que aquele método faz parte do funcionamento interno daquela classe e que o programador original quer se manter no direito de realizar qualquer tipo de alteração necessária sem se preocupar se alguém está usando ou não aquele método. Isto tem tudo a ver com encapsulamento, e pode fazer toda a diferença quando surgir a necessidade de alterar algum comportamento do objeto.
Toda vez que você constrói um novo objeto, você está construindo uma nova API. Cabe a você então decidir o que deve ser exposto e o que faz parte dos mecanismos internos deste objeto. Desta forma, quando surgir a necessidade de alterar alguma coisa, você não precisará se preocupar tanto com quantas classes serão afetadas pela mudança. Ao marcar um método como privado, você está se resguardando e garantindo que não causará danos ao restante do sistema, já que você está dentro da fronteira do encapsulamento, podendo assim refatorar seu código sem dor na consciência.
Por favor, não saia simplesmente injetando código em suas classes. Pense!
Usando o Test:Unit, se você não quiser executar todos os seus testes unitários, você pode mandar executar apenas um único caso de teste fazendo assim:
Mas se sua intenção é executar apenas um teste especifico dentro do caso de teste, você também pode fazer assim:
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:
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.
À partir do dia 24 de janeiro, Satish Talim do Ruby Learning iniciará mais um dos seus famosos cursos de Ruby. O curso é online e o material é liberado diariamente.

Mais de 5600 formados no curso de Ruby
Segundo Fernando Quadro me informou por e-mail, nesta turma já estão inscritos 450 pessoas sendo que 300 são brasileiros, mais de 60% da turma. Embora o curso seja totalmente em inglês já deu para ver que isto não é um problema tão grande assim.
Além do curso gratuito de Ruby o site também promove outros cursos pagos de Merb, Shoes, FXRuby e JRuby pelo valor simbólico de 10 dólares.
Já é possível se matricular no curso e o material já está disponível para os que desejarem se adiantar.
Desde que lancei a primeira versão do Remarkable tenho visto cada vez mais pessoas aderindo ao projeto para criar seus testes com maior rapidez. E com uma quantidade maior de pessoas usando nas mais diversas aplicações é claro que os bugs começaram a aparecer.
A maior parte dos problemas ocorriam por uma falha na arquitetura inicial do Remarkable, o que tornou necessário um refactoring no projeto inteiro para estruturá-lo melhor. Na primeira versão, internamente havia uma separação muito clara entre as duas sintaxes que o projeto oferecia. Com a reestruturação não existe mais esta separação, não importa qual é o seu estilo, RSpec ou Shoulda, internamente você sempre usará o mesmo código para realizar os testes.
Desta forma, acabamos por ganhar muitas macros novas.
Enquanto na versão em RSpec isto já era algo comum:
end
Na sintaxe do Shoulda apenas possuíamos macros should_[alguma coisa] e quase nenhuma should_not_[alguma coisa]. Mas agora todas as macros possuem as duas opções, assim:
should_belong_to :user
should_not_have_many :fleas
end
Além disso mais testes foram adicionados para garantir que problemas antigos não voltem para nos assombrar.
Para atualizar o Remarkable, execute no terminal (lembrando que no Windows não precisa usar o sudo):
Ainda falta um logo e um site para o projeto. Alguém se habilita?
O (Comovente) Guia de Ruby do Why

Acabei de atualizar o livro com novas traduções e correções. Devido a minha falta de tempo, acabei demorando para aplicar alguns dos patches que me foram enviados.
Na maioria das vezes, os colaboradores são rápidos demais e várias pessoas corrigem o mesmo texto de formas diferentes, e isto complica um pouco na hora de aceitar uma atualização. Eu tenho de olhar arquivo por arquivo antes de decidir qual será aplicado. Mas isto é bom, porque garante uma maior qualidade à tradução, embora torne o processo um pouco mais lento.
O livro pode ser encontrado na url: http://why.nomedojogo.com. Também existe uma versão para impressão em http://why.nomedojogo.com/print.html.
A processo de tradução já foi finalizado, todo o livro já está em português. Ainda falta ajustar algumas imagens e formatações de texto, mas acredito que se conseguirmos mais colaboradores teremos o livro completo e finalizado até o fim do ano.
Quer ajudar? Comece lendo o livro e quando encontrar algo errado altere aqui.

