Importando e exportando suas gems com Rubygems Snapshot 2

Posted by Roger Leite on dezembro 22, 2009

Final de ano está rendendo.
O rubygems_snapshot nasceu da necessidade de “migrar” as gems instaladas de uma máquina para outra, aliado ao rvm (veja este post-guia-rápido), permite mudar e/ou criar diferentes ambientes em minutos. Assim você pode fugir do famoso “gem hell”.

Veja como é difícil usar:

Instalação:

sudo gem install rubygems_snapshot

Para exportar as gems instaladas:

gem snapshot export projeto-exemplo.yml

Supondo que esteja em outra máquina, para importar as gems, use:

[sudo] gem snapshot import projeto-exemplo.yml

Afinal, o que tem de legal nisso?

Vamos supor que você acaba de entrar numa nova equipe e tem que montar o ambiente de desenvolvimento (por sinal, um ambiente complicado de configurar). O gem snapshot aliada ao rvm, foi feito para facilitar isto, vamos a um exemplo rápido:

Com o rvm, você pode criar um “novo ambiente”:

rvm use 1.8.7%projeto_exemplo
gem list

Deve retornar vazio.

gem install rubygems_snapshot
gem snapshot import projeto-exemplo.yml

Instalará as gems necessárias para o projeto e pronto!

ToDo:

Esta é uma versão bem básica, onde o “import” somente lê as gem e version e manda instalar sem requerir dependências. Está previsto de colocar um aviso no final das gems que deram erro, geralmente devido a dependências de “build nativos”, mas por enquanto estamos usando aqui na equipe com sucesso.

Como faço para criar um rubygems plugin também?

Bom, logo de cara posso te garantir que não é difícil (apesar da pouca documentação na internet), mas deixarei os detalhes para um outro post. Por enquanto, a minha recomendação é: clone o projeto, analise os dois rb do projeto :D e crie o seu!

Caso algum corajoso for usar, estou a disposição para ajudar, é só deixar um comentário aê!
Valeu e sucesso!

Ruby, Rubygems e $LOAD_PATH ou Como funciona o require de gems

Posted by Roger Leite on dezembro 17, 2009

Na madrugada passada, andei “brincando” com o fonte do Rubygems. Logo de cara posso te dizer que não consegui fazer o que queria, e pra amenizar o sentimento de “perda de tempo”, resolvi postar alguns truques aprendidos.

Baixei o fonte do rubygems, como faço pra rodá-lo sem alterar o meu sistema?

Foi a primeira pergunta que fiz. Percebi que com o google não iria encontrar a resposta, mas consegui uma dica importante: $LOAD_PATH.

$ irb
irb(main):001:0> $LOAD_PATH

No meu Ubuntu, obtive:

["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]
$ ls /usr/local/lib/site_ruby/1.8/

Exatamente nesta pasta que se encontra o rubygems.rb. Bingo!
Para rodar o fonte do rubygems, só é necessário adicionar ao $LOAD_PATH a pasta lib do projeto. Dado que estou na raiz do projeto rubygems baixado, execute:

~/rubygems$ ruby -I $PWD/lib ./bin/gem -v

O paramêtro -I permite adicionar diretório ao $LOAD_PATH. Simples e prático. Primeiro problema resolvido, comecei a programar.

Afinal, como funciona o “require de gems”?

Bom, já sabemos que o require “rubygems” fuciona pois encontra-se no $LOAD_PATH do ruby, no caso do meu Ubuntu em “/usr/local/lib/site_ruby/1.8″.

Basicamente (e muito), o Rubygems faz duas coisas no Kernel do Ruby.

  • Adiciona o metodo Kernel#gem.
  • Faz um Monkey Patch no Kernel#require

Kernel#gem

Permite “acionar” uma versão específica de gem. Note que este acionar, traduz-se para, adicionar a lib da gem no $LOAD_PATH. Segue um trecho do comentário do Kernel#gem:

##

# Use Kernel#gem to activate a specific version of +gem_name+.

#

# +version_requirements+ is a list of version requirements that the

# specified gem must match, most commonly “= example.version.number”.  See

# Gem::Requirement for how to specify a version requirement.

#

# If you will be activating the latest version of a gem, there is no need to

# call Kernel#gem, Kernel#require will do the right thing for you.

#

# Kernel#gem returns true if the gem was activated, otherwise false.  If the

# gem could not be found, didn’t match the version requirements, or a

# different version was already activated, an exception will be raised.
[...]

Kernel#require

No final do rubygems.rb encontramos:

if RUBY_VERSION < ‘1.9′ then

require ‘rubygems/custom_require’

end

Não consegui descobrir o que acontece com o ruby 1.9, mas no 1.8, o monkey patch executa os seguintes passos:

  • Chama o “original” require;
  • Em caso de LoadError;
    • Executa o “Gem.searcher.find(path)”;
    • Se true
      • Chama o activate (novamente traduz-se para adiciona a gem no $LOAD_PATH)
      • Executa o “original” require novamente;

Exemplos com o IRB

Para finalizar legal e comprovar tudo isso, fiz alguns testes:

$ gem list json

*** LOCAL GEMS ***

json (1.2.0, 1.1.9)

json_pure (1.2.0)

$ irb
irb(main):001:0> $LOAD_PATH

=> ["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):004:0> require "json"

LoadError: no such file to load — json

from (irb):4:in `require’

from (irb):4

from :0

irb(main):005:0> gem "json", "= 1.2.0"

NoMethodError: undefined method `gem’ for main:Object

from (irb):5
from :0

O require “json” por si só, carrega a versão mais atual da gem.

irb(main):006:0> require "rubygems"

=> true

irb(main):007:0> require "json"

=> true

irb(main):008:0> JSON::VERSION

=> “1.2.0″

irb(main):009:0> $LOAD_PATH

=> ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):010:0> quit

Após o require “json”, as pastas foram adicionadas no $LOAD_PATH.

"/usr/lib/ruby/gems/1.8/gems/json-1.2.0/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/lib"

Agora olhe que interessante este último teste:

$ irb

irb(main):001:0> require "rubygems"

=> true

irb(main):002:0> $LOAD_PATH

=> ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):003:0> gem "json", "= 1.1.9"

=> true

irb(main):004:0> $LOAD_PATH

=> ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):005:0> JSON

NameError: uninitialized constant JSON
from (irb):5

irb(main):006:0> require "json"

=> true

irb(main):007:0> JSON::VERSION

=> “1.1.9″

irb(main):008:0> quit

Note que após o gem “json”, “= 1.1.9″ … a versao 1.1.9 foi adicionada no $LOAD_PATH mas não foi carregada. Ao executar o require “json”, como este já estava no $LOAD_PATH, a versão 1.1.9 é usada.

Espero que com estas explicações, você use com mais segurança o rubygems.

Cuidado com Casos de Uso 1

Posted by Roger Leite on julho 21, 2009

Na Engenharia de Software, um caso de uso (ou use case) é um tipo de classificador representando uma unidade funcional coerente provida pelo sistema, subsistema, ou classe manifestada por seqüências de mensagens intercambiáveis entre os sistemas e um ou mais atores. Pode ser representado por uma elipse contendo, internamente, o nome do caso de uso. (fonte: Wikipédia)

A própria explicação do Caso de Uso demonstra o que costumam ser na prática, ou seja, um monte de buzzwords para enganar o usuário e levar a sua assinatura. Este por sinal, só é citado no segundo parágrafo…

É uma cilada Bino!!!

Caso de Uso!?! Pode ser uma cilada Bino!

Pontos negativos que podem tornar numa cilada:

  • Não tem público definido. Casos de Uso são feitos para os analistas, desenvolvedores, testadores e as vezes para o usuário.
  • Casos de Uso não compilam. O usuário quer um sistema e não papéis para assinar.
  • Não traz o famoso ROI, traduzindo, retorno de investimento. Já vi muitos projetos de “anos em análise”, e no final, tinham uma bíblia inútil junto com um grande rombo nas contas.
  • Difícil de manter atualizado. É natural que as coisas mudem, e a cada mudança ter que atualizar quilos de documentos, não é prático e muito caro.
  • Pelo fato de terem um público abrangente, é consumido muito tempo com detalhes inúteis, como diagramas de “tudo”, que não ajudam em nada no desenvolvimento. Mais um item que consome tempo, recurso e muito dinheiro.

A lista pode continuar fácil, mas devemos ir para a parte que interessa:

Como corresponder a expectativa do usuário?

Vou colocar o que está dando certo para mim. Caso encontrem alguma semelhança com o capítulo 7 do Pragmatic Programmer, não estranhem, foi de lá mesmo que eu me “inspirei”.

Nada melhor do que a dica 51 (uma boa idéia!) para começar:

Don’t gather requirements — Dig for them

Numa tradução livre e tosca, colocaria assim:

Não reuna requisitos, cave-os!

  • Este negócio de “cavar”, é algo como: descobrir por que o usuário faz, e não somente como. Descobrindo o por que, você consegue sugerir maneiras diferentes de como fazer. Isso nos leva a próxima dica.
  • Lembre-se que, requisitos não são arquitetura, nem design, muito menos interface do usuário. Requisitos são necessidades!
  • Não seja escravo de nenhuma anotação. Use o melhor método que se comunica com o seu público. No meu caso, papel e caneta, com rascunhos da futura tela, já está funcionando e bem.
  • Não ter medo de sugerir novas idéias. Acredito que se dependesse da maioria dos usuários, todos os sistemas teriam cara de Excel! :D Com o porque em mente, fica mais fácil sugerir funcionalidades como filtros, layout etc.
  • Some things are better done, than described. -> Algumas coisas são melhores feitas do que descritas. Pra mim, esta dica tem funcionado com reformulação de telas, algum “filtro maluco” etc.

Sei que este post é muito “abstrato”, rápido e sem referência nenhuma, mas a idéia em si é causar uma reflexão em ti, sobre o modo que tu trabalha. Hoje, ele é prático? o cliente está satisfeito com resultado? o cliente está satisfeito com a velocidade, desde a análise a concepção? está havendo desperdício de verba?

Estas perguntas são interessantes, e sempre devem ser feitas. Por mais que o software seja problemático, se conseguirmos corresponder a expectativa do usuário, teremos mais um cliente satisfeito na carteira.

O tema Caso de Uso, é polêmico, e não quero causar flame. Pra cada ambiente, equipe, produto/projeto existe uma maneira diferente de trabalhar. O que espero evitar, são aqueles papéis inúteis, com: “se a ação teve sucesso, deve mostrar ok” … bah!

Por sinal, um dos cinco grandes erros não técnicos, cometidos por programadores (original aqui) é: Esquecer do usuário. Lembre disto! ;)

Gerando cheat sheet para os snippets do gedit 1

Posted by Roger Leite on maio 05, 2009

Acredito que a maioria de vocês conhecem e/ou já usaram as famosas cheat sheets (tradução para “cola”?) para algo. Costumo usá-las quando quero fixar algum conceito novo ou simplesmente para consultas rápidas. Com o pai Google, é possível encontrar os mais diversos tipos: HTML, Ruby, Ruby on Rails, Shell Script… etc.

Atualmente venho praticando Ruby, sendo o gedit – “tunado” com vários plugins – o meu maior aliado. Um dos plugins que mais me ajuda é o Snippets e neste post do Cássio Marques, você encontra uma breve descrição do que é, e um link para snippets de exemplo.

Tudo isso foi só pra contar o que me levou a criar a gem gedit-snippets-tool. Com ela é possível criar cheat sheets dos seus snippets. Supondo que você tenha ruby e rubygem instalados, seu modo de uso é muito simples. Para instalar a gem execute:

sudo gem install rogerleite-gedit-snippets-tool -s http://gems.github.com

Após a instalação, para gerar um cheat sheet com todos os seus snippets, execute:

gedit-snippets-tool -cs > ~/mycheatsheet.xhtml

Caso tenha muitos snippets, e deseja criar um cheat sheet somente com Ruby e Ruby on Rails por exemplo, execute:

gedit-snippets-tool -cs ruby* > ~/mycheatsheet.xhtml
Meu cheat sheet de exemplo

Meu cheat sheet de exemplo

Levando em conta que a gem foi feita em três dias e focamos somente o necessário para lançarmos uma versão 0.x “em produção”, vamos as limitações:

  • O gedit-snippets-tool lê os snippets (arquivos XML) que estão na pasta “home”. Constatei que o gedit “limpo” logo após habilitar o plugin Snippets, guarda os snippets na pasta “/usr/share/gedit-2/plugins/snippets/”. Bom, se for este o seu caso, peço a gentileza de copiá-los para a “home” em “{home-folder}/.gnome2/gedit/snippets/”.
  • O template usado para gerar a página xhtml está bem “rústico”. O lado bom disso é que está bem fácil de alterá-lo. Vejam o código do template (via gist, leitores de RSS, sorry):

Quem tiver sugestões (inclusive de template), podem forkar o projeto ou se quiser, deixe um comentário que eu entro em contato.

Sobre o Desenvolvimento

Assim que tive a idéia, análisei o que seria necessário, e resumindo:

  • Ler os XMLs dos snippets;
  • Uma engine para gerar páginas através de “templates”;
  • Fazer uma gem executável… pois assim é mais fácil e rápido para quem quiser usá-la;

A parte do XML é fácil, pois até já fiz coisa parecida antes. A parte da engine para templates, o pai Google me guiou a uma ótima, chamada Erubis, que é uma gem e torna as coisas muito mais fáceis.

Para criar o esqueleto da gem, usei o gemhub do Diego Carrion, que facilitou muito o meu trabalho, sem contar a ajuda que me deu na hora de publicar o gemspec no github… valeu truta! Bom, o resto foram três noites programando e aprendendo a fazer a minha primeira gem. Quem quiser participar estão todos convidados a “forka-lo” no github.

Business Bingo Generator 4

Posted by Roger Leite on abril 13, 2009

Para quem tem algum tempo de internet, é fácil notar como as piadas se repetem, ou melhor, assim como olimpíadas ou copa do mundo, re-aparecem a cada quatro anos por exemplo. Não foi diferente com a piada que recebi (novamente) a pouco tempo, o Business Bingo. O que torna a piada muito divertida é o seu alto teor sarcástico e real, foi quando pensei, porque não imprimir esta cartela e realmente testar! Foi assim que surgiu a idéia de fazer um gerador de cartelas para o Business Bingo! :D

idéia

Business Bingo! Generator

A idéia deste post, além de ajudar a divulgar o site, é ter um local central para comentários, sugestões, reclamações e elogios para o Business Bingo Generator.

Curiosidade

  • O Business Bingo, também conhecido como Buzzword Bingo, ganhou notoridade em 1994, com uma tirinha publicada do Dilbert.
  • Um dos “grandes” eventos “documentados”, foi em 1996, que alunos do MIT o usaram no discurso do vice-presidente dos EUA, Al-Gore.

Uma nota rápida a desenvolvedores

A primeira versão foi desenvolvida em dois dias, isso mesmo, dois dias e já estava em produção. Eu e o Rodrigo Panachi resolvemos implementar a idéia do “generator” para aprender na prática como funciona o Ruby on Rails. Num post futuro irei colocar mais detalhes técnicos, que apesar de ser uma aplicação muito pequena, podemos tirar proveito de grandes aulas. Para quem quiser contribuir, o Business Bingo Generator está no GitHub.

TPW – Dicas para a qualidade do Software 1

Posted by Roger Leite on janeiro 15, 2009

Desenvolvedores em geral sabem como é chato quando uma tela que fez ou alterou dá erro durante uma homologação ou até produção. No caso de um sistema Web, a raiva aumenta ainda mais se a causa for incompatibilidade de navegadores.

Antes de começar a apresentar o “the best of my rotina”, é bom deixar bem claro o meu cenário:

  • Trabalho sozinho no projeto, sou humano e faço pair programming com a cpu, que eu tenho certeza que é pogger!
  • O meu cliente, o que requisita correções e/ou novas funcionalidades, é um cliente interno e eu tenho acesso direto a ele.
  • O sistema não tem testes unitários, testes de integração e etc.
  • Muito código foi copiado, não somente na camada de negócio, mas também nas views. As páginas por aqui, também são conhecidas como business-view.
  • Tem mais complicações, mais acho que já tem o suficiente para entenderem o meu cenário.

O que já fizemos para começar a arrumar a casa:

  • Implantamos um bug tracker, conhecido como Redmine. Sabe aquele velho problema de planilha pra lá e pra cá e ninguém nunca sabia quem, e o que estava fazendo? Pois bem, este problema está quase resolvido aqui (quase porque ainda tem projeto faltando para migrar).
  • Implantamos um servidor de integração continua, com o Hudson. Apesar de eu não ter testes, havia um sério problema aqui para implantar novas versões em homologação e produção, e agora com o Hudson centralizando o build, ele mesmo já disponibiliza o war.
  • Por sinal, montar e começar a usar o war foi outro trampo também.

Sabendo que o meu contexto é diferente do seu, sinta-se livre para adaptar qualquer coisa. Tentei deixar as dicas o mais genérico possível.

1. Trabalhe com tarefas Curtas

Tarefas curtas são muito mais fáceis para desenvolver, testar e se livrar! Por exemplo, se tem que desenvolver aquele formulário com vinte telas, não tenha dúvida, quebre isto em pequenas funcionalidades. Para identificar as partes “quebráveis”, leve em conta o que a torna funcional, ainda no exemplo anterior, se das vinte telas, você fizer a primeira e a última são suficientes para um cadastro básico, está ai a sua primeira tarefa. Muitas pessoas não dão importância para isso, mas saber “extrair” as tarefas certas de um novo desenvolvimento ou manutenção, traz um leque de vantagens:

  • Testar uma funcionalidade curta é muito mais rápido e fácil do que testar uma gigantesca;
  • Fica mais dificil perder o foco.
  • Os prazos ficam mais “coerentes”.
  • Você pode retirar ou incluir novas funcionalidades, a “negociação” com o cliente fica mais simples.

2. Monte e use um roteiro de teste

Pra quem usa TDD, este passo pode pular. Pra quem trabalha com legados e ainda não tem testes (meu caso), eu costumo fazer um roteiro de testes antes de implementar a funcionalidade curta. Este roteiro costuma ser enxuto e abrangente, isto permite que eu descanse meu cerebro enquanto testo, pois com ele, acaba se tornando um processo mecânico. Vou colocar um exemplo recente de roteiro que usei:

Teste de Primeiro Acesso

  • Limpar a base, apagar os registros da tabela xpto e suas dependências.
  • Limpar os cookies.
  • Acessar o index.jsp da Aplicação (esta página simula um login via cookie).
  • A tela inicial só permite cadastrar os dados do perfil, os links “xxx” e “zzz” não ficam disponíveis.
  • Após o Teste de Restrições ao Editar o Perfil, verificar que os links “xxx” e “zzz” estão disponíveis.
  • Clicar em salvar novamente para verificar se o problema de “unique id” não ocorre.

Estes roteiros se tornaram um costume, eu perco pouquissimo tempo pra fazer e apesar de parecer besta, ele me ajuda muito na hora de executar um teste de sanidade por exemplo. O ideal seria transformar este roteiro num teste unitário ou até mesmo num script via Selenium, mas devido a estrutura (ou a falta dela?!) eu ainda não consegui esta automação tão sonhada.
Apesar deste roteiro ser descartável e somente para ajudá-lo, uma idéia legal que venho fazendo é colocá-lo como comentário caso use um bug tracker.

3. Teste seu sistema num ambiente isolado

Estes últimos dois anos tenho usado linux no desktop para desenvolvimento. Infelizmente, todos nós sabemos que todo sistema web tem que ser testado nos IE*s e cia. É claro que durante o inicio do desenvolvimento, uso meu firefox local mesmo, mas assim que termino a funcionalidade, uso uma máquina virtual para averiguar a compatibilidade com os navegadores mais utilizados.
Usando o Virtual Box e Multiple IEs mais o opcional roteiro de testes, consigo validar o sistema numa boa gama de navegadores. Para usar o Multiple IEs não tem segredo, é só atualizar para o IE7 e depois rodar o executável do mesmo.

4. Automatize o que for possível

Já ocorreu de você precisar preencher n campos, navegar em n telas e descobrir que você errou o nome de uma variável javascript e ter que fazer tudo de novo? Pois bem, comigo já aconteceu muito, e uma das soluções que venho usando é o Selenium Ide. Com o plugin do firefox, eu gravo scripts temporários (durante o desenvolvimento da tarefa) que preenche os n campos e navegam nas n telas, assim pelo menos este tempo de navegação eu só perco uma vez.

Finalizando …

Todas estas “técnicas” nada mais são do que uma retrospectiva minha, de uma tentativa (frustada por sinal) de Scrum Solo. Aqui estou colocando o que vem dando resultado, e se você achou besteira ou legal, gostaria muito do seu comentário. Sabe aquela frase da maça e conhecimento, então, minha única expectativa com este post é esta: Novas Idéias!

Valeu e feliz ano novo a todos!

Arquiteto Cascateiro 4

Posted by Roger Leite on novembro 07, 2008

Este post é uma homenagem aos Arquitetos defensores do waterfall/cascata.

Recentemente tive o desprazer de conhecer um arquiteto, é isso mesmo, aquele com certificado e tudo, com direito a broche da Sun em seu terninho. Aliás, certificado é um tema polêmico que eu não tenho uma opinião muito certa e/ou formada… bom, vou deixar esta parte para um próximo post, quem sabe.

Voltando ao assunto, hoje no fretado, comecei a pensar nas semelhanças que um arquiteto de sistemas (certificado que decorou patterns inutéis da Sun) tem com um arquiteto de obras. Só para deixar claro, na tabela abaixo estou usando dois estados: FAIL e Ok. Fail quer dizer que vai dá merda não vai dar certo e não tem jeito, caso queira uma definição mais formal, o wikipédia ajuda, agora se você prefere imagens, o Fail Blog também serve.

Exemplo de FAIL

Exemplo de FAIL

Objetivos Cascateiro De Obras
Colocam as futuras “obras” no papel antes de começar. FAIL OK
Ainda no papel, colocam todas as necessidades do cliente, do início ao fim. FAIL OK
O cliente do Arq. de Obras sabe que depois que começar não pode mudar. FAIL OK
O arquiteto de Obras não define quais tipos de blocos, cimento e ferro a obra vai usar, o Cascateiro sim. FAIL OK

Parei a tabela por aqui pois já dá pra saber que o FAIL tende a infinito né.
Pergunta: o que ambos arquitetos estão fazendo!?!
Resposta educada: Estão fechando o escopo do projeto.

Arquiteto Cascateiro trabalhando ...

Arquiteto Cascateiro trabalhando ...

A resposta acima é uma frase chave pra você ter certeza que vive num projeto waterfall cascateiro. Fechar o escopo do projeto inteiro deve ser muito bom para o arquiteto de obras, já para um sistema, o efeito é contrário. Acredito muito na teoria que desenvolver software não é construir prédios. Livros de renome como Pragmatic Programmer citam isso.

Sei que este tema de construção civil já está batido. Comecei a escrever este post ao mesmo tempo que o Sr. Panachi publicou o anterior, e com a idéia de ficar menos repetitivo, já vou linkar as sugestões dos nossos incríveis leitores:

  • O Diego Carrion (grande peruano! :D ) cita este link, que fala que a engenharia civil também consegue ser ágil em alguns casos.
  • O Witaro, fez um ótimo post “Desenvolvendo software como uma Rock Band” que quebra a barreira da analogia com a engenharia civil. Cara, continue escrevendo, porque a sua visão é muito legal!

Bom, agora que acabou o desabafo, vamos as possíveis soluções. O que fazer com o Arquiteto Cascateiro?

Acho que a primeira coisa seria conscientizá-lo de que ele não é o Oscar Niemeyer e que a primeira versão de seu software nunca será completa de uma vez. Você deve conversar sobre iterações com ele e mostrar que o software deve evoluir conforme o cliente também evolui nas descobertas das suas reais necessidades. Sei que o post já está cheio de links, mas este post do Phillip Calçado, Analista Pedreiro, resume bem o que quero dizer.

Arquiteto, este nome ou termo ou cargo ou seja-lá-o-que-for, é coisa de modelo waterfall/cascata. Numa equipe, não deve haver distinção desta maneira. Todos programam, modelam, configuram, trabalham no Banco de Dados quando necessário, ou seja, ninguém deve exercer um papel único. Papéis únicos, representam Guardiões que defendem somente seus interesses e não trabalham em pró da equipe/cliente/projeto.

O Arquiteto deve programar, colocar a mão na massa, assim como toda a equipe, pois UML, Caso de Uso, Diagrama de Sequência, etc. sempre compilam! Muito diferente na vida real, onde muitas vezes você é obrigado a implementar uma coisa diferente e torta para acompanhar estes documentos cascateiros. Caso você seja obrigado a gerar a documentação fútil acima, pense em algo que seja automatizado após você ter programado e testado, com certeza você será umas cinco vezes mais produtivo.

E por último e não menos importante, a equipe (inclusive o Arquiteto) tem que conhecer o negócio que implementa. Quando se inicia um novo projeto ou até mesmo decidem reestruturar um existente, o arquiteto cascateiro sempre prioriza novas tecnologias e frameworks, o que na maioria das vezes, não é necessário. Novos projetos ou refactoring em existentes, devem ter um único prioritário objetivo: KISS. Com esta prioridade em mente, novas tecnologias e frameworks serão escolhidos naturalmente, e não somente usar porque é a última moda no estilo SunTechDays.

E vocês leitores?! Sofrem ou já sofreram muito com Arquitetos Cascateiros!?!

Rails Summit ! Eu fui ! 2

Posted by Roger Leite on outubro 18, 2008

Não sei nem como começar a descrever o evento, foi muito bom !!! Logo no primeiro dia, na fila para pegar o pequeno cracha de identificação, já trombei logo com quem !?! Dr. Nic ! E ao seu lado, estava um cara muito simpático também, que de primeira não reconheci, o Chad Fowler e sem barba ! E pra quem não acredita, bom, tirei foto com o figura como prova ! (está aqui no album do flickr)

Palestrantes RailsSummit

Palestrantes RailsSummit

Todas as palestras foram muito interessantes, no segundo dia, o tema testes foi muito abordado e acabou ficando repetitivo, porém o pessoal aproveitou para atualizar seus e blogs e tals. Na minha humilde opinião, as apresentações de abertura e final do evento foram as melhores ! Na abertura, destaque para o video que o pessoal do Rails Envy mandou !

Sem se preocupar em parecer repetitivo, mas a principal mensagem das palestras foram, “faça!”. Tudo se resume a ação!, ajude projetos open, crie novos projetos, participe com diferentes papéis, leia, escreva blogs, livros, screencasts, wikis … etc. Teve muita mensagem motivacional, e eu confesso que gostei ! :D

É complicado tentar repassar a enxurrada de informação que veio do evento, e por serem parecidas, eu acabo misturando as informações. Resumão: Metodologias Agéis, teve bastante coisa sobre e com perspectivas diferentes, cool!

Parte do Chad Fowler, foi muito legal, com sacadas interessantes do “meio corporativo”, e apresentou questões filosoficas sobre a evolução de frameworks. Logo em seguida, teve uma conferência com o DHH (David Heinemeir Hansson), falou sobre o futuro de Rails, falou sobre thread-safe do Rails 2.2.

Palestra do Brando foi muito legal, e deu uns toques importantes de como conseguir aquele seu emprego rails tão desejado, sem contar o chefe dele, Carl, grande figura.

Depois teve o Chris Wanstrath (criador do github.com), é impressionante o tanto que ele batalhou pra chegar aonde o github é hoje, foi meio chato porque ele ficou lendo, mesmo assim, teve informações legais.

No final, o BOF (Birds of a Feather) foi um show a parte! Várias figuras, falando desde projetos em desenvolvimento até a técnicas de impor novas idéias … várias figuras, várias risadas.

O segundo dia de evento, começou muito interessante, com a apresentação muito boa – dei muita risada em várias partes – Ninh Bui e Hongli Lai os emos caras do Phusion ! Foi muita piada nerd, várias animações flash, citações de mega man à dragon ball, com direito a Star Wars no final …

Phusion Darth Vader !

Phusion Darth Vader !

Depois assisti a palestra do Jay Fields. Foi muito legal, ele apresentou o lado bom e ruim de vários frameworks de testes como selenium, rspec e talz. Destaque para o momento flame, quando o David Chelimsky mantenedor do rspec, começa a questionar alguns pontos levantados por Jay. Não se preocupem, que tudo acabou em breja …

Assisti a palestra do Vinicius Teles, cara, sensacional ! A palestra foi sobre empreendedorismo, com participação especial do Carl (da SurgeWorks), ficou muito legal a “union” das apresentações, e esta com certeza merece um post separado-extra.

Chegando ao final do dia, começou a bater o cansaço … assisti a palestra do Fabio Kung sobre JRuby. Ele entrou em detalhes na plataforma Java e como é executado o código ruby nela. Foi muito legal, porque eu finalmente entendi a diferença entre “servers” e talz. Eu não lembro muito ao certo, se eu tiver acesso a apresentação, coloco o link aqui.

Pra finalizar teve o fechamento com o Obie Fernandez, ele mostrou de maneira apaixonada e apaixonante, como está funcionando sua nova empresa, a HashRocket. Mostrou o manifesto agil, primeiro em papel e depois na vida real com os fatos da sua empresa. Mostrou que testes funcionam, programação em par também funciona! e etc. Foi muito show, acho muito legal a forma que ele conduz a apresentação.

1up4dev and ... Obie !

1up4dev and ... Obie !

O evento fechou com chave de ouro, rolando várias brejas, e isso eu te garanto, é muito louco brindar com o Dr. Nic e Obie na mesma roda ! :D

Além de tudo isso, é muito interessante como o espirito de “integração” é muito alto, por exemplo, o Diego Carrion do MouseOver Studio ficou com nosso grupo, os dois dias, trocamos experiências, foi show também. Até agora, a única apresentação que peguei foi a do Dr. Nic, que ele disponibilizou o link via twitter.

Me desculpem pelo tamanho do post … e como ele está muito grande, nem vou ler em busca de erros, vou arrumando conforme necessário, ou seja, fica pro próximo sprint !

TPW – Colocando dicas em prática 5

Posted by Roger Leite on agosto 18, 2008

Depois de ler The Pragmatic Programmer é natural ficar empolgado, bom, uma prova disso foi meu próprio post sobre o assunto. Depois de ter “digerido” o livro, lancei as dicas para o desenvolvedor, acabei inventando um termo legal The Pragmatic Waterfall, que resolvi transformá-lo numa série.

A primeira dica do “dicas para o desenvolvedor”, foi:
- Gerador de código descartável.

Pois bem, hoje, vou mostrar um exemplo de “código descartável” que utilizei e deu certo ! :D

Problema: No projeto que estou existem algumas queries em arquivos XML do hibernate, preciso convertê-las para Spring. Pra cada query do hibernate, precisei gerar dois arquivos de XML do Spring e mais uma classe Java que herda de SqlUpdate … blá blá blá. Bom, os detalhes não importam muito, o que importa é que vamos ler o XML do hibernate e gerar o que for necessário, tudo isso com Ruby!

Antes de qualquer coisa, já aviso que ainda não domino totalmente Ruby, e o script que fiz é do tipo código “descartável”, então não tive o menor cuidado em deixá-lo bonito, apenas funcional. Acho que a melhor maneira de aprender uma nova linguagem é escrevendo código com ela, não somente lendo sobre.

Exemplo super simplificado do XML do Hibernate:
script generator-bean em Ruby:

É isto ! O script é simples e direto, deixei a saida pro console mesmo e para jogar em arquivo é muito simples:

$ ruby generator-bean.rb > spring-exemplo.xml

O script que coloquei é uma versão bem reduzida, já que a idéia do post é mostrar que é possível transformar tarefas chatas e trabalhosas em scripts semi-automáticos ! Ah, lembrando que com ele consegui terminar a minha tarefa em 2 dias, sendo que a previsão era quase uma semana de trabalho !

Precisa de mais informações de como ler XML com Ruby !?

Segue as referências.
Tirei deste post, muito legal por sinal.
* API do REXML: http://www.ruby-doc.org/stdlib/libdoc/rexml/rdoc/index.html
* Sobre o Electric XML: http://www.xml.com/pub/r/1098
* Tutorial um pouco mais complexo sobre XML com Ruby: http://www.xml.com/pub/a/2005/11/09/rexml-processing-xml-in-ruby.html

OBS: Estou usando o gist.github.com para colocar o xml e script de exemplo, provavelmente não vai aparecer no leitor de feed.

Maior Evento de Rails da América Latina

Posted by Roger Leite on agosto 05, 2008

Divulgação:

Pessoal, o Akita deu a Largada para o Maior Evento de Rails da América Latina!

Eu não vou perder ! O mais difícil foi convencer a patroa do gasto no cartão de crédito ! :D


Rails Summit Latin America

Pra quem quiser ir aquecendo os motores, e codificando Ruby, vou deixar alguns links ! (Coloquei o blogroll do meu Reader, não sei se vai aparecer via feed ! Pros curiosos, acessem o post.)

Comecei a participar da lista rails-br, dentre as várias discussões interessantes, tem esta, Brazilian Rails Blogs, com mais blogs sobre Rails.

Sucesso! E nos encontramos lá !