Sistemas de Arquivos em Ruby

Por algum motivo, pensei se isso seria mais uma das “coisas que você nunca quis fazer com Ruby”, mas acho que não, até porque estou num projeto para usar tal funcionalidade. Mas, por via das dúvidas, vamos fazer algo BEM estranho:

Para quem não conhece, o FUSE (Filesystem in Userspace), uma extensão do Kernel do Linux (e do MacOSX, se não me engano), serve principalmente para criar sistemas de arquivo. Isso significa, se você sempre teve vontade de acessar sua base de dados como se fosse uma sequência de diretórios, por exemplo, esse pacote é para você. Mas, como já existem exemplos demais assim, vamos fazer algo mais bizarro (para variar): integrar o Twitter com FUSE.

Para tal tarefa, você precisará das gems “twitter” e “fusefs”. Basta instalá-las com “gem install fusefs twitter”, arregaçar as mangas, e partir para o próximo passo.
(more…)

Nokia n810 e iPod Touch-comparação

Bom, para os que me conhecem, sabem que eu não sou nem um pouco adepto da Apple, principalmente porque os equipamentos que ela faz são extremamente fechados e difíceis de hackear. Isso, para um desenvolvedor, é praticamente um pesadelo, e esse foi o motivo que me levou a comprar, a alguns meses, um Nokia n810.

Para os que não conhecem, o n810 é um tablet (ou um “mini tablet”, talvez) que roda Linux (maemo). É considerado por muitos como o antecessor do n900, que atualmente é o sonhado brinquedo de muitos.

Bom, como sempre, a primeira coisa que eu fiz, quando ele estava já carregado, foi ver o que eu poderia fazer com ele: até onde eu poderia chegar. Instalei outro browser (mirori), e tentei abrí-lo… e ganhei uma mensagem de erro. Quando reiniciei o n810 (sim, precisei reiniciar porque nenhum aplicativo abria mais), consegui abrir o midori, e descobri que ele era BEM melhor que o browser que acompanha o nokia. Por sinal, isso foram coisas que eu fui descobrindo com o tempo, que a maioria dos aplicativos que já vem com o Nokia são bem ruins.

Em compensação, desenvolver para o nokia é uma maravilha. Basta usar sua linguagem favorita (menos Java) e escrever o código, que ele roda tranquilamente (ambiente semelhante ao do Gnome). Mais para frente, tentei usar o GPS dele, e basta dizer que o GPS aí simplesmente não funciona-ele demora uns 20 minutos para achar os satélites, depois demora para achar a posição atual, e ainda consome muita bateria.

No FISL, este ano, ganhei um iPod touch, no Code Golf. Resolvi ver quanto tempo eu conseguiria usá-lo sem Jailbreak, e marquei o tempo de duas horas-a maioria do que eu queria instalar só rodava num iPod desbloqueado. Até o momento, não consegui descobrir uma forma fácil de desenvolver em qualquer coisa diferente de Objective-C, como Ruby ou Python, por exemplo, além de ter achado demasiadamente complicado passar músicas e fotos para o Touch (o gtkpod é o aplicativo mais recomendado, embora eu preferiria que o touch montasse como uma pen-drive). Além disso, a bateria do touch é bem fraquinha na minha opinião (a minha dura pouco mais de 24 horas, com o iPod completamente em repouso e sem usar wireless).

Ok, chega de problemas, vamos falar de características:
(more…)

FISL – Minha palestra, e Code Golf

Pretendo ainda fazer um resumão do FISL, mas por enquanto vamos a palestra e ao Code Golf.

Durante o FISL, apresentei a palestra “Lapidando Ruby”, um estudo de boas práticas em programas Ruby e em Rails. Basicamente, uma apresentação sobre as diversas práticas que eu percebi que levavam a um código melhor. Como eu disse na apresentação, parte do estudo é que as pessoas discordem de algumas coisas que eu faço. Pela reação do pessoal, acho que muitas pessoas concordaram com a maioria do que eu falei. A apresentação está no slideshare, e está abaixo (nota, que é melhor baixar o arquivo do SlideShare, fica um pouco melhor do que a apresentação que eles colocam lá):
(more…)

Resumo do Agile Brazil – Segundo Dia

No segundo dia, o evento começou mais tarde devido ao jogo. A primeira palestra que vi foi “Refatoração de Testes”, com Eduardo Guerra. Foi uma palestra razoável na minha opinião, mas achei interessante justamente a preocupação com a refatoração. Um dos pontes fortíssimos da palestra foi a definição das partes de um teste: “Setup” (deixar o programa numa determinada situação), “Assertion” (a verificação propriamente dita), e o “Teardown” (limpar os dados que o programa fez). De acordo com Guerra, o teste pode mudar completamente, mas as “Assertions” devem manter-se íntegras.
(more…)

Resumo do Agile Brazil – Primeiro Dia

Semana passada, fui ao evento AgileBrazil, promovido pela PUC do Rio Grande do Sul. Foi um evento de quatro dias, embora os dois primeiros tenham sido reservados apenas para mini-cursos (XP, Coaching, etc – infelizmente, quando fiz minha inscrição não haviam mais vagas para estes cursos). Apesar de algumas falhas na organização (eu, particularmente, achei muito ruim o número de palestras simultâneas – no geral haviam quatro palestras ao mesmo tempo, além de Open Spaces entre outros. Achei ruim não ter conseguido participar de nenhum open space, mas é a vida), o evento contou com um nível técnico muito bom, ao meu ver, com palestras extremamente interessantes.

O evento começou com um Keynote do Martin Fowler, no qual ele apresentou três pequenas apresentações. Em uma delas, ele apresentou os perigos da gerência de software da forma como tem sido feito, fora do mundo ágil, apresentando que no passado, o sucesso era definido se o plano inicial foi seguido (o que ele considera um absurdo, pois um sistema pode ter sido bem-sucedido sem sequer ter sido posto em produção). Em seguida, ele citou sobre “Technical Debt”, um termo para indicar quando as boas-práticas são ignoradas, no desenvolvimento de software, em prol de uma série de coisas tal como “precisamos atender o prazo”, etc. Ele cita que tal débito precisa ser cuidadosamente controlado, caso contrário fica a produtividade começa a cair (e cita que o tempo que este débito pode sair do controle é medido em semanas, e não em meses como se achava). Por fim, sua última apresentação falou sobre integração contínua, no qual ele citou como faz seus “deploys”, no qual em cada Commit ele gera um executável que vai para uma bateria de testes (Smoke Tests, e Aceptance Tests), para depois cair em uma segunda bateria (mais Smoke Tests e Performance Tests) para, por fim, ir para produção (com mais Smoke Tests). Citou também o software Cruise, mas não entrou em muitos detalhes.
(more…)

O Vendedor de Sonhos

Estes dias, li o livro O Vendedor de Sonhos. Basicamente, o livro é uma ficção disfarçada de auto-ajuda, ou uma auto-ajuda disfarçada de ficção – eu não saberia dizer, embora se fosse para chutar, diria que é o segundo. Basicamente, é a história de um personagem que tenta se suicidar, e encontra um homem que diz que vende sonhos, e o convida para acompanhá-lo na empreitada. É uma ficção, o que talvez tenha me motivado a ler até o fim do livro, ao invés daqueles livros que repetem diversas vezes “você é a pessoa mais importante da sua vida” e mais blá blás. Mas há alguns pontos muito positivos que eu gostaria de mencionar.

Primeiro, o personagem é bem identificável – talvez, porque o autor do livro é psicólogo, então ele não inventou personagem cheio de problemas sem explicações. Talvez, alguns personagens sejam estereotipados demais, talvez tenham menções demais a religião, talvez o autor tenha desejado dar a idéia de que ninguém é culpado pelos seus atos, são apenas vítimas de um sistema que engole a todos, mas em linhas gerais, é uma boa história. Porém, algo me chamou mais a atenção neste livro do que simplesmente a história ou a auto-ajuda (que eu, particularmente, não suporto, mas tudo bem):

Lições.
(more…)

O que é Eingenclass, afinal?

Bom, eu acredito que algumas pessoas que começaram com a linguagem Ruby possam ter essa pergunta. O que, exatamente, são Eingenclass (ou, na nomenclatura mais comum, Singleton Classes)? O que, exatamente, retorna o método “metaclass”, do ActiveSupport? Bom, em primeiro lugar, é bom entender algumas coisas: o código a seguir:

class Exemplo
end

e1 = Exemplo.new
e2 = Exemplo.new
def e1.imprimir
  puts "Algo"
end

e1.imprimir #Imprime Algo
e2.imprimir #NoMethodError

Por que a primeira instância ganhou um método chamado “imprimir”, e a outra não? Para onde foi a definição deste método? Para dar a resposta, é necessário primeiro entender alguns conceitos importantes. Em primeiro lugar, sempre que um método é definido, ele é definido em uma classe, e a partir deste momento ele está disponível para ser chamado por uma instância. Este é um conceito interessante: embora, quando façamos códigos como:

class Exemplo2
  def self.somar(a, b)
    a + b
  end

  def um_metodo
    "um método"
  end
end

a tendência é chamar o método “somar” de “class method” ou “metodo da classe”, na verdade não é isso que acontece. Este método, na verdade, não foi definido na classe Exemplo2, e sim em outra classe da qual a classe Exemplo2 é apenas uma instância. Para os que conhecem melhor a estrutura de classes do Ruby, sabe que toda classe é uma instância da classe Class, e sabe também que definir um método como o “somar”, acima, não automaticamente adiciona esse método a todas as outras classes. É aí que entram as Eigenclasses
(more…)

Dá para criar classes abstratas em Ruby?

Ok, aqui vamos nós para mais estudos de como fazer coisas bizarras em Ruby… outro dia, estava olhando para um livro, “Design Patterns in Ruby”, que falava de classes abstratas (tipo Java) e a inexistência delas em Ruby, aonde “Duck Typing” resolve. Mas aí pensei: será que não dá para simular o comportamento de classes abstratas tipo Java, em Ruby?

Para os que não conhecem Java: se você, em Java, declarar uma classe como abstrata, e definir, digamos, dois métodos abstratos, quando esta classe for herdada, você é obrigado a definir estes dois métodos, senão o código sequer compila. Bom, parece então simples, em Ruby: basta criar uma classe, informar, de alguma que ela é abstrata, e então quando ela for herdada, se a classe herdada não definir todos os métodos, lançar uma exceção (digamos, um NoMethodError). Ok, Ruby permite traçar quando uma classe foi herdada com o método “callback” inherited, portanto é relativamente simples saber se a classe foi herdada e se ela implementa os métodos da abstrata, certo?

Bom, na prática… não.
(more…)

O Usuário SEMPRE Sabe o que Quer

Não, não é uma pergunta. O título deste post, embora pareça contraditório com o que a maioria das pessoas desenvolvedoras de sistema dizem, quer dizer exatamente o que ele quer dizer. Depois de muito tempo trabalhando com desenvolvimento de sistemas, e um ano trabalhando direto com métodos ágeis (no qual um usuário é livre para fazer mudanças) a frase que mais me perturba é quando alguém diz: “o usuário nunca sabe o que quer”, seguida de perto pelas “o usuário é folgado” ou “o usuário não usa o sistema que desenvolvemos pra ele”.

Primeiro ponto a ser feito, é que ninguém se pergunta “POR QUE o usuário não usa o sistema”, ou “POR QUE ele é folgado”. O que faria uma pessoa usar uma planilha de excel, com todas as dificuldades e inseguranças que ela oferece, ao invés de um sistema? Preguiça de clicar em trocentos botões? O sistema é lento? O sistema é “muito chato”, tipo, milhares de validações, etc? Tudo isso, é o usuário lhe dizendo que o sistema não é do jeito que ele quer – e se o sistema foi desenvolvido PARA ele, por que um programador culpa o usuário, se a falha foi de si mesmo ao ter desenvolvido algo que o usuário não queria?
(more…)

Traçando a Execução em Bibliotecas de Terceiros (em Ruby)

Ontem, acredito que esbarrei feio num bug do Ruby 1.8 (não sei se outras versões estão com o mesmo problema). Para encurtar a longa história, estava mexendo num código usando TheRubyRacer semelhante ao seguinte (nota: se você não entender o código a seguir, vale a pena dar uma olhada em meu post anterior):

class UmaClasse
  def method_missing(method, *args, &b)
    puts "Método #{method} chamado!"
    ...
  end
end

require 'v8'
context = V8::Context.new
context['classe'] = UmaClasse.new
p context.eval('classe.um_metodo')
p context.eval('classe.um_metodo = 10')

O que eu esperava, é que na linha 11, fosse impressa a mensagem “Método um_metodo chamado!”, porém o que aconteceu não foi bem isso. Quando olhei para a documentação da biblioteca, descobri que ela expõe apenas os métodos públicos por padrão, agora COMO ela fazia isso… isso já é outro problema. Então, num primeiro momento, resolvi remover todos os métodos da classe UmaClasse, e ver o que acontecia:
(more…)