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…)

Conectando Javascript e Ruby

Bom, a algum tempo vi uma biblioteca chamada Harmony, para Ruby, que tenta fazer esse processo. Porém, eu achei alguns problemas na biblioteca que meio que me impediam de usá-la do jeito que eu queria, então acabei encontrando uma outra alternativa: The Ruby Racer.

Esta biblioteca usa o interpretador V8, o mesmo usado no Google Chrome, para interpretar Javascript. Possui uma API bem simples, e consegue incorporar objetos Ruby no Javascript de uma forma bem transparente. Como exemplo, digamos que queremos expor uma classe Ruby para o Javascript. Basta usar o código a seguir:

require 'v8'

class UmaClasse
  def initialize(nome)
    @nome = nome
  end

  def imprimir_nome
    puts @nome
  end
end

js = V8::Context.new
js['uma_classe'] = UmaClasse.new
js.eval('uma_classe.imprimir_nome()')

Este código conectará, no Javascript, um objeto chamado uma_classe. Para instalar a biblioteca, um simples “gem install therubyracer” basta, na maioria das vezes. Quando isso não funciona (que nem o meu caso)…
(more…)

Dá para fazer tipagem estática em Ruby?

Bom, resolvi começar uma série – coisas que você NUNCA quis fazer com Ruby, e tinha medo de perguntar. Basicamente, pensei em montar códigos absurdos de coisas que são completamente contra a filosofia da linguagem, ou que pelo menos são muito esquisitas, e publicar aqui os resultados. As regras são simples: os resultados devem ser testáveis (com RSpec, de preferência) e devem ser escritas puramente em Ruby, de preferência sem nenhuma biblioteca auxiliar (e, se for necessário usar, é obrigatório que a biblioteca tenha sido escrita puramente em Ruby também).

Como primeiro da série, vamos simular uma tipagem estática em Ruby. Como é impossível sobrescrever o operador “=” em Ruby, resolvi usar uma função – static – para simular o mesmo comportamento. Para simplificar, vamos meio que definir uma “variável global” com “static.”, e definir que esta terá tipagem estática. Começamos definindo uma função chamada “static”

def static
  Static.instance
end

(more…)

Porque o Rubinius é importante.

Muita gente já falou sobre o assunto, e eu percebi, até agora, que não dei minha opinião então…

Para as pessoas que estão interadas, Rubinius é uma implementação de Ruby sobre Ruby. Parece estranho, e é um pouco mesmo, então vale a pena mostrar mais como isso funciona. Nos outros interpretadores, uma boa parte das classes padrão da linguagem são implementadas em C (ou Java, no caso do JRuby). Em Rubinius, estas classes são implementadas em Ruby sempre que possível, e a máquina virtual (VM, atualmente estão usando o LLVM) é extremamente simples e otimizada. Com isso, além de Ruby ficar muito mais flexível (mais? sim, é sempre possível) ainda se ganham alguns conceitos interessantes. Para fazer esta “mágica”, é necessário um compilador que traduz código Ruby para bytecodes que serão executados na LLVM – e Rubinius escreveu este compilador totalmente em Ruby. Pode parecer um conceito absurdo, mas não é – o próprio compilador C da Gnu, o GCC, é escrito em C.
(more…)

Ensaio Sobre a Violência

Este será um post totalmente off-topic*, mas tudo bem.

Quando eu era mais novo, lá para a minha pré-adolescencia, lembro de ter assistido ao filme “Ghost – do outro lado da vida”. Muitos já devem tê-lo assistido também. Lembro que na época, meu pai estava começando a seguir o espiritismo, e não lembro mas acho que foi por este exato motivo que estávamos assistindo ao filme. Lembro também de ter comentado que os vilões meio que se matavam sozinhos, e meu pai concordou comigo, mas por algum motivo aquilo não me pareceu certo… parecia que tinha algo muito errado com o filme, com a forma como o personagem principal enfrentava os vilões, mas antes de explicar direito o que eu pensei, vamos para outro filme: “Jogos mortais”. Numa primeira comparação, parece que o vilão de Jogos mortais é bem mais cruel e perverso do que o mocinho de Ghost, porém fazendo uma comparação mais completa, isso não é verdade.

Vendo pelo seguinte lado: em Ghost, o personagem principal morre, e como fantasma caça seus assassinos. Quando os encontra, os assombra até que eles, assustados como nunca, acabam se matando “sozinhos”. Soa familiar? O estranho é que, para a maioria das pessoas, Sam (de Ghost) não é um “vilão” como o de Jogos mortais, por exemplo, embora a atitude de ambos os personagens é exatamente a mesma. Talvez possam vir papos do tipo “mas os personagens que Sam mata são assassinos, e ele faz isso sem intenção, blá blá”, mas a verdade é que isso não importa a mínima – a reação que parecemos ter quando uma pessoa é morta difere demasiadamente dependendo se a pessoa era “boa” ou “má”.
(more…)