Tuesday, January 6th, 2009

Balanço cultural de 2008

Mesmo sendo um ano agitado, deu para ler e ver bastante coisa em 2008. Não vou fazer uma lista de destaques como fiz no ano passado, mas só comparar rapidamente os números:

  • Livros: 68 (68 no ano anterior)
  • Filmes: 73 (106 no ano anterior)
  • Séries: 94 (200 no ano anterior)
  • Contos: 12 (nenhum no ano anterior)
  • Quadrinhos: 2 (nenhum no ano anterior)
  • Teatro: 1 (não lembro no ano anterior)

Consegui ler o mesmo tanto de livros, o que é bom. Reduzi o número de filmes e séries, o que também é bom, considerando que a safra do ano passado não foi lá essas coisas.

Estou começando a ler alguns quadrinhos novamente, aproveitando que o pessoal da WebCo possui vários dos clássicos que fizeram época. Confesso que sou um péssimo conhecedor do assunto e nesse final de ano comecei a seguir algumas recomendações. Vamos ver o que dá no próximo ano.

Finalmente, vergonha completa em qualquer coisa que exija sair de casa. ;) Nesse ano agora, espero conseguir ir mais ao teatro, ouvir mais orquestrar e, em geral, fazer mais coisas do tipo.

Posted by Ronaldo | Filed in Filmes e Séries, Livros e Literatura | 2 Comments »

Tuesday, January 6th, 2009

Balanço cultural de dezembro

Dezembro foi um mês bem atípico para mim nas leituras. Depois dos primeiros quinze dias agitados, resolvi tirar férias pela primeira vez em quatro anos. O resultado foi o seguinte:

  • 3 livros
  • 35 episódios de séries

Comecei o mês com Halting State, de Charles Stross. Stross é um dos poucos autores que consegue escrever sobre futuros próximos de uma forma plausível. Seus livros são cheios de especulações tecnológicas e sociais que poderiam muito bem ser as notícias de amanhã e Halting State não é uma exceção.

Nesse livro, o ponto focal é o roubo de um banco–com o detalhe de que o banco é localizado em um jogo que é essencialmente uma versão futura do World of Warcraft. A partir disso, Stross pinta uma novela detetivesca em um mundo onde a convergência já aconteceu e realidade consensual é algo do dia-a-dia, explorando as implicações disso tanto para os relacionamentos entre as pessoas como para a diplomacia internacional.

Seguindo no mês, completei mais uma passo da minha educação cyberpunk lendo Snow Crash, de Neal Stephenson. Eu sei que é uma vergonha confessar, mas eu ainda não li muitos dos romances originais do movimento. Estou recuperando agora.

Snow Crash é um Stephenson clássico, com o mesmo humor, verve e capacidade de extrapolação exibida nos livros mais recentes do mestre do cyberpunk. Só mesmo Stephenson para chamar o seu personagem principal de Hiro Protagonist e torná-lo um samurai, hacker e entregador de pizza. Além disso, é impressionante como um livro de 1992 pode parecer completamente atual. Nada do que ele escreve sente datado.

A estória segue Hiro e seus vários associados enquanto ele tenta descobrir o mistério por trás de uma droga virtual chamada Snow Crash cujo alvo específico são os hackers e os mistérios por trás dos seus criadores e distribuidores. Leitura perfeita para geeks.

Finalmente, terminei o mês lendo Hyperion, por Dan Simmons. Do Simmons eu havia lido anteriormente Ilium e Olympus, sua duologia pós-humana reconstruindo a guerra de Tróia em um futuro distante e fiquei impressionado com sua mistura de pós-tecnologia e literatura (baseada primariamente em Shakespeare, Homero, Proust e Nabokov). Hyperion estava na fila há tempo por ter ganho o Hugo e segue o mesmo padrão, desta vez misturando The Cantebury Tales e John Keats.

Obviamente, por ser mais antigo, o livro demonstra um domínio menor das técnicas que tornaram o trabalho de Simmons famoso e o fato de que eu li os trabalhos posteriores primeiro implicou em notar algumas falhas que eu não teria notado de outra forma. Mesmo assim, gostei do livro o suficiente para prosseguir pelos outros três que seguem Hyperion e estou quase terminando o quarto e final.

Nas séries, só mesmo completando o que ainda não tinha visto das que eu acompanho nos corridos meses anteriores. Com a exceção de uma menção desonrosa para Heroes, que permanece uma porcaria completa, estou esperando somente os retornos do próximo ano.

Agora é só seguir para a fila do próximo ano. :)

Posted by Ronaldo | Filed in Filmes e Séries, Livros e Literatura | Comment now »

Tuesday, December 16th, 2008

Arrogância, hubris e simples orgulho

Uma “modinha” entre desenvolvedores Rails atualmente é transformar arrogância em uma virtude a ser cultivada. É fácil entender a razão. A briga pelo campo de linguagens dinâmicas, a necessidade de se provar viável e sustentável deixou suas marcas. O problema é entender o tipo de arrogância necessária, algo que passa batido não só no campo Rails como em essencialmente todas outras auto-denominadas comunidades.

Larry Wall, criador do Perl, dizia com razão que hubris, ao lado de preguiça e impaciência, são virtudes de todos bons programadores. Hubris é um termo originalmente grego que denotava orgulho excessivo, uma auto-confiança que desafiava os deuses, e que, muitas vezes, terminava com resultados trágicos para o indivíduo que exibia o comportamento–como Prometeu, por exemplo.

Wall transformou essa idéia negativa na positiva do zelo que um programador deve ter ao criar programas limpos e claros que causam orgulho e que levam outros programadores a perceberem as qualidades do código. Um virtude, nesse sentido, interessante.

Arrogância pode ser uma arma. Voltando ao Rails, David Heinemeier Hansson a utilizou com eficiência para criticar problemas válidos no campo da computação–alguns dos quais estavam impedindo o desenvolvimento e adoção de novos conceitos que hoje são bem mais comuns do que quando o Rails foi lançado.

Como em vários comunidades, muita gente começou a emular esse comportamento como se o mesmo fosse uma justificação própria. O que, ironicamente, leva a um círculo completo terminando no mesmo ponto em que os detratores do Rails estavam originalmente. Nada mais comum hoje ver um desenvolvedor Rails defendendo seu amado framework com unhas e dentes como se o mesmo fosse a única opção válida. Java & .NET anyone?

Não há coisa pior do que o tipo de arrogância que se acha sempre correta. A hubris sabe dizer “não sei, mas vou remediar isso”–seja aprendendo algo novo ou admitindo que outra pessoa pode ajudar. O resto é simples, e completamente banal, meninice.

Bons programadores exibem o tipo de atitude que Larry Wall definiu. Arrogância, pura e simples, leva a alguém que não aprende, que vai se defasando pouco a pouco até que tenha que partir para a tecnologia do jour mais uma vez para se manter relevantes.

Confesso que me cansei dessa primeira variedade de arrogantes. São esses os que não aprendem a lição de Santayana e daqui a vinte anos estarão no mesmo ponto em que estão hoje. Pater, dimitte illis, non enim sciunt quid faciunt.

Posted by Ronaldo | Filed in Comportamento | 8 Comments »

Tuesday, December 16th, 2008

Convergência, redes sociais, realidade aumentada e gaming spaces

Eu sempre acreditei que a convergência tecnológica não se daria na Web e sim no celular. Quanto mais o tempo passa, mais estou certo disso. Quanto mais cedo as empresas se convencerem disso–e pode ter certeza de que a Apple está olhando dez anos à frente nisso, ergo o iPhone–mais elas estarão próximas de seus usuários.

Das minhas últimas leituras sobre redes sociais, um assunto que meio que passa desapercebido da literatura é a convergência que está sendo realizada em torno de gaming spaces.

No Brasil–e mesmo nos Estados Unidos e Europa–a falta de jogos de realidade consensual mais ativos como uma atividade regular mascara isso mas basta olhar para a Ásia e ver que mais uma vez estamos atrasados no assunto. No Japão, jogos envolvendo geo-localização e realidade aumentada são um dos setores mais ativos da indústria móvel. Na China, a moeda virtual do QQ, a maior plataforma móvel local, é tão forte que não só é aceita em lojas comuns como incomodou o governo ao ponto de regulamentação ser necessárias.

Declarar que o ser humano é social é óbvio. Perceber a interseção disso com o espaço de jogos em que existimos não é tão fácil. Nossas carreiras são literalmente arquiteturadas ao redor de jogos que possuem implicações reais e imediatas. Transpor isso para um World of Warcraft é só uma maneira secundária de visualizar a questão–igualmente válida e igualmente importante.

É claro, existe uma grande dependência em torno de grandes transformações necessárias para uma materialização de alguns cenários. Primeiro, sem feedback háptico é mais difícil transpor a barreira para a parte aumentada da realidade–e um tanto ou quanto menos satisfatório. Segundo, um ambiente seguro, criptografado e distribuído por padrão é necessário. Terceiro, alguns jardins fechados precisam ser abertos pelos menos parcialmente.

Os dois primeiros pontos acima podem ser resolvidos com mais alguns anos de avanço tecnológico. O último vai depender de um tipo de reengenharia humana em escala global que pode demorar mais tempo para acontecer. Já começou mas pode tomar décadas ainda no pior caso.

De qualquer forma, o ponto inicial permanece: convergência móvel é um fato agora e vão sair na frente as empresas que aproveitarem isso.

Posted by Ronaldo | Filed in Tecnologia, Vida | Comment now »

Monday, December 15th, 2008

Exterminaram Terminator

Eu confesso que realmente tinha gostado do começo de Terminator: The Sarah Connor Chronicles. A segunda temporada, entretanto, até onde vi agora, está falhando miseravelmente. A minha previsão de que a parte de viagens no tempo se tornaria mais problemática se concretizou e os roteiristas não sabem mais onde enfiar tantos novos exterminadores.

Viagem do tempo é sempre algo difícil de fazer. Com exceção de uns poucos filmes como De Volta para o Futuro e Os 12 Macacos, é mais fácil falhar do que contar uma estória coerente. A questão é que chega uma hora que a coisa toda se converte em uma enorme seqüência de deus ex machinas que torna tudo inteiramente despropositado.

No caso das crônicas, a Skynet envia exterminadores para o passado que seria mais fácil mover a guerra para os dias atuais e dominar tudo antes de que a coisa começasse. A estratégia de mandar um exterminador após o outro é insultante para inteligência dos fãs. Aliás, a coisa toda poderia se resolvida pela Skynet de uma vez por todas se removendo para o futuro e mandando ordens do futuro profundo. Avançar o suficiente no cone histórico para ser quase impossível desalojá-la sem acabar com o resto.

Enfim, a série parece estar fazendo um sucesso moderado e deve continuar por mais um tempo. Mas o futuro é o mesmo do Smallville que divergiu tanto do cronologia oficial que só pode ser considerada uma linha alternativa. É bom, mas é ruim ao mesmo tempo. Eu preferia ver algo mais coerente com o original.

Posted by Ronaldo | Filed in Filmes e Séries, Geral | 5 Comments »

Friday, December 12th, 2008

Agile para sua diversão e lucro

Meu irmão, como já citei outras vezes aqui, tem uma pequena operação em Belo Horizonte prestando serviços em software livre para empresas no Brasil e nos Estados Unidos. Atualmente, a maior parte do trabalho é em Rails e estamos sempre conversando sobre como melhorar e aumentar a eficiência do que ele e o pessoal que trabalha lá estão fazendo.

Recentemente ele me visitou na WebCo e ficou bem curioso ao ver as dezenas de post-its colados nas várias janelas representando os diversos projetos da empresa. Expliquei um pouco de Agile–usávamos várias técnicas agéis quando eu ainda estava na empresa–mas Scrum era uma coisa que eu ainda não tinha comentado com ele.

Depois que ele voltou para Belo Horizonte, ele me ligou pedindo que eu explicasse um pouco mais sobre os tais dos sprints. Explique mais um pouco e sugeri que ele experimentasse mesmo com a equipe pequena.

Mais algum tempo passou e em mais uma de nossas conversas ele me explicou com tinha adaptado o que eu estava falando para a realidade de sua empresa:

Com R$126 ele comprou um quadro, alfinetes, post-its coloridos, canetas e marcou as tarefas de vários projetos com cores diferentes para identificar os mesmos. Mesmo tarefas administrativas da empresa foram colorizadas e colocadas no quadro. Ele também separou o progresso das mesmas em “a fazer”, “em progressos” e “feitas”, como no Scrum, mas sem a formalização de daily meetings.

Como isso, ele começou a poupar uma quantidade enorme de trabalho de gerenciamento e acompanhamento de tarefas ao mesmo tempo em que dava maior visibilidade a todos da empresa sobre o que estava acontecendo. Eventualmente, o quadro também se tornou uma reflexão do sistema Trac que ele usa para controle de tickets aumentando ainda mais a produtividade da equipe.

Para alguns puristas, a adaptação que ele fez seria considerada tão longe do Scrum quando um processo waterfall. Esse é o ponto que a maioria das pessoas perde sobre Agile:

Agilidade não tem absolutamente nada a ver com formalização. Assim como waterfall funciona para determinados tipos de processo–existem milhares de casos de extremo sucesso usando a filosofia–agilidade só funciona quando a idéia em si é comprada e adaptada à realidade específica dos processos necessários.

No caso do meu irmão, daily meetings com formalizados no Scrum não tem o menor sentido com a equipe pequena e geograficamente distribuída. Aplicar todos os parâmetros que o Scrum oferece teria o efeito contrário de reduzir sua produtividade.

Antes de tudo vem o lúdico, a diversão. E isso leva tão facilmente ao lucro que é impressionante pensar no número de pessoas enganadas quanto à história toda. Mas eu me divirto e sempre sou lembrado de pensar diferente quando vejo adaptações como a feita pelo meio irmão que funciona e resulta em efeitos permanentes positivos. Melhor do que isso é difícil.

Posted by Ronaldo | Filed in Desenvolvimento | 11 Comments »

Thursday, December 11th, 2008

Balanço cultural de novembro

Também com alguns dias de atraso–o novo BlogBlogs foi lançado ontem com sucesso–finalmente tive tempo de escrever o balanço cultural de novembro. Como o mês foi ainda mais movimentado do que outubro, o resultado foi bem pequeno:

  • 4 livros
  • 2 quadrinhos
  • 7 filmes

Nos livros comecei com uma releitura de Atlas Shrugged. Fazia tempo que eu estava querendo revisitar o épico trabalho de Ayn Rand que define sua filosofia objetivista–não por ser um adepto–mas pela força do trabalho. A estória do homem que decidiu parar o motor do mundo e assim o fez é um tour de force em pensamento claro e narrativa forte. Apesar de ser condenado por alguns como verboso e prolixo, eu gosto do modo com Rand apresenta os caracteres e transpõe sua filosofia para o enredo sem acabar em pedantismo. Com exceção do capítulo em que o personagem principal define a filosofia em um discurso, o resto do livro é belo e consegue despertar a mente do leitor para as questões propostas sem incomodar.

O segundo livro foi The Graveyard Book, o novo infanto-juvenil de Neil Gaiman. Leitores regulares conhecem minha admiração perene pelo trabalho de Gaiman e esse livro me deixou tão satisfeito como seus demais trabalhos. Embora Coraline, seu trabalho infanto-juvenil anterior não tenha me agradado tanto, essa releitura d’O Livro da Selva de Rudyard Kipling na estória de um garoto criado por fantasmas é uma delícia de leitura.

Na seqüência li Test-Driven Development by Example, de Kent Beck, um dos maiores evangelistas dessa metodologia. O livro é simples e direto ao ponto mas falha colossalmente em não terminar os exemplos começados. O resultado é a sensação de que os exemplos são artificiais demais. Isso termina passando uma imagem ruim da técnica e deixando o leitor insatisfeito. O livro poderia ter se beneficiado enormemente de mais algumas dezenas de páginas.

Finalmente, li The Name of the Wind, o primeiro de um trilogia de Patrick Rothfuss. Atualmente é muito raro que eu leia um livro que é parte de uma série antes que a mesma esteja fechada. Entretanto o livro recebeu tantos elogios de autores que eu considero muito bons que não resisti e comprei. Não me arrependi. A estória é fascinante e eu devorei o livro. Só para dar o gosto, um pequeno trecho do mesmo (o site do livro contem todo um capítulo):

I have stolen princesses back from sleeping barrow kings. I burned down the town of Trebon. I have spent the night with Felurian and left with both my sanity and my life. I was expelled from the University at a younger age than most people are allowed in. I tread paths by moonlight that others fear to speak of during day. I have talked to Gods, loved women, and written songs that make the minstrels weep.

You may have heard of me.

Nas estórias em quadrinhos, li o primeiro volume das Crônicas de Sandman, também por Neil Gaiman (roteiro, é claro). O primeiro volume compreende as primeiras oito estórias publicadas sobre o Senhor dos Sonhos, todas fascinantes. Como fã de Neil Gaiman eu sou suspeito para falar, mas como sempre ele consegue produzir uma mistura mitológica que é absolutamente impossível não se impressionar com a pura força da estória e a quantidade de referências que Gaiman consegue por em tão poucas páginas. Já estou com os próximos volumes para finalmente corrigir esse problema na minha educação “quadrinística”. :)

Nos filmes, o mês foi razoavelmente melhor que o anterior.

Comecei o mês com Michael Clayton. George Clooney está muito no papel de um advogado envolvido em negócios escusos tentando salvar sua pele e sua família e Tilda Swinton é sempre consistente em seus papéis.

Em um mesmo fim de semana vi There Will Be Blood e No Country for Old Man. É absolutamente assustador o que alguns atores bons conseguem fazer. No primeiro, Daniel Day-Lewis mais uma vez se prova um dos atores mais poderosos de sua geração e no segundo Javier Bardem fornece uma atuação magnífica que me prendeu do começo ao fim. Fica difícil decidir qual dos dois está melhor em seus respectivos papéis e, definitivamente, ambos mereceram todos os prêmios que ganharam.

Quantum of Solace foi bem inferior ao filme anterior na franquia Bondiana mas consegue divertir. Eagle Eye também é divertido mas depende de um furo enorme do enredo para fazer sentido.

Os demais, como sempre, nem valem o comentário. :)

Posted by Ronaldo | Filed in Filmes e Séries, Livros e Literatura | 2 Comments »

Saturday, December 6th, 2008

Balanço cultural de outubro

Com mais de um mês e meio de atraso–falta de tempo com o lançamento próximo do BlogBlogs e viagens diversas–consegui escrever sobre os livros e filmes vistos em outubro. O resultado do mês foi:

  • 7 livros
  • 10 filmes

Nos livros, o primeiro que li no mês foi Emissaries from the Dead, de Adam-Troy Castro. Eu já tinha lido alguns contos do autor, todos excelentes–inclusive, seu conto The Tangled Strings of the Marionettes é um mais belos e nostálgicos que eu já li–e ao encontrar o livro na Livraria Cultura resolvi comprar. O livro se passa em um futuro onde a humanidade é uma de milhares de raças que habitam a galáxia e não uma das particularmente melhor posicionadas. Quando um assassinato acontece em uma missão diplomática humana em uma colônia artificial criada por uma AI, uma diplomata humana deve investigar a situação sem implicar os criadores da colônia. O resultado é uma novela detetivesca bem decente que peca apenas em seus momentos finais ao tentar condensar muita informação em infodumps que acabam não sendo tão interessante. Mesmo assim, se houver uma continuação, está na minha lista.

Seguindo, li Equal Rites, de Terry Pratchett. É um dos livros mais antigos do mundo Discworld e com a cômica premissa de uma confusão em torno de passagem de poder entre magos que resulta na primeira mulher nessa posição em toda história do Discworld. Como todos livros do Pratchett, o humor é bem sarcástico e mórbido. E como nos primeiros livros do Pratchett, o final é bem fraco, fechando a história mas sem tanto impacto.

O próximo livro foi Agile Software Development with Scrum, de Ken Schwaber e Mike Beedle. O livro foi um dos primeiros a popularizarem o Scrum com uma metodologia/filosofia/processo aceitável de forma geral. O livro consegue um bom balanço de didática e evidência anedótica e explica bem os conceitos por trás do processo. Para quem não tem conhecimento algum ou está começando, é uma boa leitura introdutória.

Continuando, li Doomsday Book, de Connie Willis. O livro ganhou tanto o Hugo quanto o Nebula em sua publicação e a autora é bem conhecida por trabalhos fortes e contemplativos. A estória do livro é sobre uma estudante de História que consegue autorização para viajar ao ano de 1320 para estudar localmente os hábitos da Idade Média. Infelizmente, uma crise ligando o passado e o futuro interfere e ela se vê lançada em uma época muito pior tendo que lidar com situações inesperadas e dolorosas. O livro é belo em suas descrições e enredo mas acaba sendo um tanto ou quanto previsível. O final, em particular, pode ser visto de longe. Mesmo assim, vale a leitura pela força narrativa.

O livro seguinte foi A Fila sem Fim dos Demônios Descontentes, de Bruna Beber. Eu sou super-suspeito para falar já que a Bruna é colega de trabalho e me deu o livro de presente, mas eu realmente gostei da poesia da garota. A Bruna é carioca tresloucada e extremamente competente no que tange à escrita e isso se reflete claramente em seus poemas. :-) De pequenos e doces arranjos a poemas fortes e contundentes, ela consegue uma série de textos memoráveis que valem leituras repetidas.

Quase fechando o mês, foi a vez de The Enterprise and Scrum, também do Ken Schwaber. O livro é quase uma revisão do Agile Software Development with Scrum com aplicações para empresas de porte maior. O livro falha razoavelmente ao tentar cobrir muito material em pouco espaço que faz do mesmo quase uma coleção de apêndices. Vale correr o olho, mas não acrescenta muito ao corpo de material existente.

Finalmente, terminei o mês com The Black Swan, de Nassim Nicholas Taleb. O livro foi aclamado como um dos melhores do ano pela sua suposta explicação de eventos improváveis, mas confesso que, se a explicação está lá, ela está misturada e perdida em meio a centenas de divagações e digressões em que o autor mistura pseudo-ciência, fatos de sua vida e uma atitude de superioridade que com certeza agrada a fãs de verbosidade e explicações “rebuscadas”. O livro tem alguns méritos em quebrar algumas concepções, mas é pouco mais do que uma compilação do que outros autores vem falando há vários anos sob um verniz de modernidade e erudição. Boring, boring, boring.

Nos filmes, foi um mês bem fraco. Tirando o belo The Assassination of Jesse James by the Coward Robert Ford e interessante 3:10 to Yuma, os demais quase não valem o comentário. Desses dois, o primeiro consegue demonstrar muito bem a ambigüidade por trás dos fatos conhecidos sobre a relação entre Jesse James e Robert Ford e o segundo consegue resgatar muito bem o espírito real do primeiros filmes e livros de faroeste.

The Invasion, em contrapartida, consegue ser mais um caro e fracassado remake de um bom filme. Há diretores que realmente acreditam que uns poucos sustos e atores famosos são suficientes para convencer uma platéia de que um filme tem estória. Hitman é um fiasco de execução que nem a bela Olga Kurylenko consegue salvar (inclusive, parece que o diretório de Quantum of Solace pensou a mesma coisa que o diretor de Hitman). Finalmente, P.S. I Love You poderia ter sido um belo filme sobre morte e recuperação mas se transforma em um drama barato e choroso.

Os demais filmes realmente dispensam comentários.

Posted by Ronaldo | Filed in Filmes e Séries, Livros e Literatura | 1 Comment »

Thursday, November 13th, 2008

Flay, eliminando repetições em código Ruby

Flay é uma ferramenta útil para cercear repetições de código em programas Ruby. Analisando o código semanticamente, o Flay é capaz de pegar repetições em casos que geralmente passam despercebidos no melhor dos códigos.

Em algumas casos, a repetição será inevitável e mesmo necessária para deixar o código mais legível. Geralmente, entretanto, repetição significa código que ainda não está DRY o suficiente.

Instalação

Para instalar o Flay, basta rodar o comando gem:

~$ sudo gem install flay

Esse comando instala a gem em si e um executável que pode ser usado na linha de comando.

Um exemplo

Para demonstrar o uso da ferramenta, vamos rodar o Flay contra o código mais recente do Active Record:

O resultado (um trecho apenas), depois de alguns minutos de trabalho com a CPU a 100%, é o seguinte:

Matches found in :defn (mass = 290)
  ./test/cases/associations/join_model_test.rb:237
  ./test/cases/associations/join_model_test.rb:262
  ./test/cases/associations/join_model_test.rb:271
  ./test/cases/associations/join_model_test.rb:623
  ./test/cases/associations/join_model_test.rb:650

Matches found in :defn (mass = 270)
  ./test/cases/validations_test.rb:929
  ./test/cases/validations_test.rb:937
  ./test/cases/validations_test.rb:945
  ./test/cases/validations_test.rb:953
  ./test/cases/validations_test.rb:961
  ./test/cases/validations_test.rb:969

Matches found in :defn (mass = 236)
  ./test/cases/validations_i18n_test.rb:491
  ./test/cases/validations_i18n_test.rb:510
  ./test/cases/validations_i18n_test.rb:529
  ./test/cases/validations_i18n_test.rb:549

Matches found in :scope (mass = 204)
  ./test/migrations/duplicate/3_innocent_jointable.rb:12
  ./test/migrations/interleaved/pass_1/3_innocent_jointable.rb:12
  ./test/migrations/interleaved/pass_2/3_innocent_jointable.rb:12
  ./test/migrations/interleaved/pass_3/3_innocent_jointable.rb:12
  ./test/migrations/missing/4_innocent_jointable.rb:12
  ./test/migrations/valid/3_innocent_jointable.rb:12

Matches found in :call (mass = 172)
  ./test/models/author.rb:64
  ./test/models/project.rb:17

Matches found in :defn (mass = 171)
  ./test/cases/validations_test.rb:977
  ./test/cases/validations_test.rb:991
  ./test/cases/validations_test.rb:1079

Note especialmente código que está sendo repetido em arquivos diferentes. No caso acima, como o código está em arquivos de teste, é provável que a repetição seja desejável para não poluir o escopo dos mesmos.

Vamos tomar um outra caso na biblioteca em si:

Matches found in :if (mass = 165)
  ./lib/active_record/associations/has_and_belongs_to_many_association.rb:82
  ./lib/active_record/associations/has_many_association.rb:100
  ./lib/active_record/associations/has_many_through_association.rb:194

O código repetido em questão é o seguinte:

if @reflection.options[:counter_sql]
  @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
elsif @reflection.options[:finder_sql]
  # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
  @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
  @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
else
  @counter_sql = @finder_sql
end

Vendo os arquivos, é possível observar que o código é o mesmo. Considerando que os três arquivos representam classes com um pai em comum seria possível reduzir a repetição movendo o código para um método a classe pai.

Esse tipo de repetição tende a sumir com refatoramentos e o código acima provavelmente sumirá por um processo similar (alguém se habilita para um patch?).

Conclusão

Como é possível perceber, o Flay representa mais uma forma de observar o seu código em busca de coisas que podem ser melhoradas. É claro que isso não deve ser converter em uma obsessão de remover toda e qualquer repetição, o que demoraria mais tempo do que codificar coisas novas.

Como de usual, sugestões, críticas e dúvidas são bem-vindos.

Posted by Ronaldo | Filed in Programação, Ruby | 2 Comments »

Thursday, November 13th, 2008

Flog, analisando complexidade em Ruby

Flog é outro analisador de complexidade para Ruby. Diferentemente do Saikuro, que mede a complexidade ciclomática real do código, o Flog tem o propósito de mostrar padrões de tortuosidade no seu código. É mais uma ferramenta interessante e de fácil uso para analisar a evolução da complexidade do seu código:

Instalação

Para instalar o Flog, basta rodar o comando gem:

~$ sudo gem install flog

Esse comando instala a gem em si e um executável que pode ser usado na linha de comando.

Um programa de exemplo

Para demonstrar o uso da ferramenta, vamos utilizar o mesmo exemplo que mostrarmos no artigo sobre o uso do Saikuro.

require "test/unit"

class DocumentHasher

  def initialize(object, options = {})
    @object = object
    @options = options
  end

  def hash
    hash = { :id => @object.id }
    if @options[:fields]
      @options[:fields].each do |field|
        hash[field] = @object.send(field)
      end
    end
    if @options[:extra_fields]
      @options[:extra_fields].each do |field|
        hash[field] = @object.send(field.to_s + "_field")
      end
    end
    hash
  end

  def self.hash(object, options = {})
    self.new(object, options).hash
  end

end

class DocumentHasherTest < Test::Unit::TestCase

  Struct.new("HashExample", :id, :title, :author)

  TITLE_FIELD = "Test"
  AUTHOR_FIELD = "Author"
  EXTRA_FIELD = "Extra"

  def setup
    @object = Struct::HashExample.new(1, TITLE_FIELD, AUTHOR_FIELD)
    class << @object
      def extra_field
        "Extra"
      end
    end
  end

  def test_hash_id
    result = DocumentHasher.hash(@object)
    assert_equal 1, result[:id]
  end

  def test_hash_fields
    result = DocumentHasher.hash(@object, 
      :fields => [:title, :author])
    assert_equal TITLE_FIELD, result[:title]
    assert_equal AUTHOR_FIELD, result[:author]
  end

  def test_hash_extra_fields
    result = DocumentHasher.hash(@object, 
      :fields => [:title, :author], 
      :extra_fields => [:extra])
    assert_equal EXTRA_FIELD, result[:extra]
  end

end

Salve esse arquivo para um arquivo chamado hasher.rb e rode-o com o comando abaixo para verificar sua execução:

~$ ruby hasher.rb

Utilização

Com esse programa, podemos rodar o Flog. O comando é simples:

~$ flog hasher.rb

Resultado inicial

O resultado da execução acima pode ser visto na listagem abaixo:

Total Flog = 57.7 (7.2 +/- 62.8 flog / method)

DocumentHasher#hash: (27.3)
     9.0: send
     8.6: assignment
     5.8: []
     5.4: branch
     2.8: each
     1.9: to_s
     1.7: +
     1.5: new
     1.3: hash
     1.3: id
DocumentHasherTest#setup: (8.3)
     6.5: sclass
     1.3: assignment
     1.3: new
     0.4: lit_fixnum

Note que o método hash possui um fator de “tortuosidade” de 27 e que os maiores culpados são o envio de mensagens (send) e atribuições. A “tortuosidade” total do programa está em 57.7, que representa o cômputo de todos os métodos do programa.

Alterando o programa

Para fins de exemplo, podemos tentar reduzir a complexidade do método hash como fizemos no artigo anterior usando o exemplo abaixo:

require "test/unit"

class DocumentHasher
  
  def initialize(object, options = {})
    @object = object
    @options = options
  end
  
  def hash  
    hash = { :id => @object.id }
    build_fields(hash, @options[:fields] || {})
    build_extra_fields(hash, @options[:extra_fields] || {})
    hash
  end
  
  def self.hash(object, options = {})
    self.new(object, options).hash
  end
  
  protected
  
  def build_fields(hash, fields)
    fields.each do |field|
      hash[field] = @object.send(field)
    end
  end
  
  def build_extra_fields(hash, fields)
    fields.each do |field|
      hash[field] = @object.send(field.to_s + "_field")
    end
  end    
  
end

class DocumentHasherTest < Test::Unit::TestCase
  
  Struct.new("HashExample", :id, :title, :author)
  
  TITLE_FIELD = "Test"
  AUTHOR_FIELD = "Author"
  EXTRA_FIELD = "Extra"
  
  def setup
    @object = Struct::HashExample.new(1, TITLE_FIELD, AUTHOR_FIELD)
    class << @object
      def extra_field
        "Extra"
      end
    end
  end
  
  def test_hash_id
    result = DocumentHasher.hash(@object)
    assert_equal 1, result[:id]
  end

  def test_hash_fields
    result = DocumentHasher.hash(@object, 
      :fields => [:title, :author])
    assert_equal TITLE_FIELD, result[:title]
    assert_equal AUTHOR_FIELD, result[:author]    
  end

  def test_hash_extra_fields
    result = DocumentHasher.hash(@object, 
      :fields => [:title, :author], 
      :extra_fields => [:extra])
    assert_equal EXTRA_FIELD, result[:extra]
  end
  
end

Rodando o comando novamente, teríamos:

Total Flog = 58.1 (5.3 +/- 10.3 flog / method)

DocumentHasher#hash: (10.7)
     3.2: []
     3.0: branch
     2.6: assignment
     1.5: new
     1.3: build_extra_fields
     1.3: hash
     1.3: build_fields
     1.3: id
DocumentHasher#build_extra_fields: (9.4)
     4.2: send
     2.8: assignment
     1.8: to_s
     1.6: +
     1.3: branch
     1.3: each
DocumentHasherTest#setup: (8.3)
     6.5: sclass
     1.3: assignment
     1.3: new
     0.4: lit_fixnum
DocumentHasherTest#test_hash_fields: (7.0)
     3.0: []
     2.6: assert_equal
     1.3: hash
     1.3: assignment

Note que a complexidade dos métodos caiu substancialmente. Os métodos estão mais simples e mais balanceados. A “tortuosidade” geral subiu um pouco com a adição de algumas chamadas, mas, analisando os métodos individualmente é possível observar que a somatória de complexidade dos três métodos envolvidos é menor do que a complexidade original. Mais uma vez, o código está mais legível e mais testável.

Conclusão

O Flog representa uma métrica arbitrária de complexidade que, mesmo assim, pode ser usada para acompanhar o desenvolvimento de um base de código. Um exemplo disso pode ser visto no texto do Carlos Villela mostrando a evolução do código do Rails ao longo dos anos.

Como de usual, sugestões, críticas e dúvidas são bem-vindos. No próximo artigo, esfolando o seu código Ruby com mais ferramentas de análise de complexidade.

Posted by Ronaldo | Filed in Programação, Ruby | Comment now »