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.

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!

Foco no problema 1

Posted by Rodrigo Panachi on novembro 10, 2008

Desenvolver software é uma atividade muito gratificante pois sempre podemos (ou deveríamos) exercitar nossa criatividade para solucionar os problemas dos clientes. Isto, apesar de divertido pode ser perigoso e/ou catastrófico se estivermos com o foco errado. Num ambiente cascateiro, onde cada envolvido está comprometido apenas com o processo e não se preocupa verdadeiramente com os problemas dos clientes, não é difícil que isto ocorra. Quase sempre o foco acaba sendo direcionado para a solução ao invés do problema.

Mas qual a diferença entre foco no problema ou solução? Vamos a um exemplo:

Quando a Nasa enviou os primeiros astronautas ao espaço, descobriu que as canetas não funcionavam com gravidade zero. Para resolver esse problema, os engenheiros contrataram uma empresa especializada para projetar a caneta espacial.
Dez anos e US$ 12 milhões depois, estava pronta a caneta que podia ser usada no espaço, em qualquer posição. Nem a temperatura poderia atrapalhar: a supercaneta funcionava bem fizesse frio ou calor.
Os russos, que tiveram o mesmo problema, optaram por uma solução mais simples: passaram a usar um lápis.

A história acima é bem famosa e mesmo sendo falsa, demonstra muito bem o que acontece quando o problema não está em foco. Neste caso, o problema é a impossibilidade de escrever em gravidade zero. Uma das soluções seria uma caneta que escreva nessas condições. Veja que aqui a solução já está em foco. Outra solução para o problema seria utilizar algo que escrevesse em gravidade zero: um pedaço de carvão ou um giz já serviriam. Assim, o problema seria resolvido.

Outro exemplo de falta de foco no problema é esta história da fábrica de pasta de dente, onde ocasionalmente algumas caixas da pasta de dente eram entregues vazias. Para eliminar este problema, a empresa gastou investiu milhões para garantir que durante a fabricação, nenhuma caixa ficasse sem o tubo de pasta de dente dentro. Mas o problema foi realmente resolvido depois que um operário deixou um ventilador soprando as caixas vazias para fora da esteira de produção. Simples não?

Na área de desenvolvimento de software não é tão raro acontecer algo parecido, onde o foco está inteiramente na solução. Sabe aquele sistema meio capenga, que funciona e dá dinheiro para empresa mas não é “web 2.0″ nem utiliza conceitos de “SOA”? De repente a diretoria decide que este sistema deve ser “migrado” para uma tecnologia da moda mais atual, que o permita “evoluir” mais facilmente.

Para atender esta necessidade, normalmente uma equipe nova é contratada, toneladas de documentos e diagramas são produzidos até que os programadores comecem a codificar. A esta altura, o prazo já está apertado e os “stakeholders” ainda não viram os resultados. Depois de muito tempo e dinheiro desperdiçados, um sistema feito às pressas, bonitinho mas meia-boca, é entregue com os mesmos defeitos do anterior. E o problema não foi resolvido…

Desenvolver software deve ser um investimento lucrativo, proporcionando algum ganho às partes envolvidas. Quando uma necessidade surgir, o primeiro passo é identificar o problema para então encontrar a melhor solução, ou seja, foco no problema. Neste exemplo da “migração”, o problema é que a manutenção do software atual é muito cara, porém “migrar” o sistema inteiro não vai resolver o problema, no máximo criará um novo.

Mas de quem é a culpa quando o foco está na solução? Eu respondo: a cascata! Apesar das metodologias ágeis estarem em alta e aos poucos serem adotadas pelas empresas, a maldição do waterfall ainda é está entre nós. Clientes continuam com a mania de pedir tudo no início do projeto. Ao exporem seus problemas, já estão pensando na solução. Fazem questão de engordar o escopo com coisas das quais não têm certeza da utilidade, mas querem que estejam lá pois podem precisar um dia. Os desenvolvedores também não estão isentos dessa culpa. Um legítimo analista cascateiro não se envolve com os problemas do cliente, apenas ouvem suas solicitações e transformam em casos de uso ou diagramas. É aí que uma simples necessidade se transforma numa bola de neve e a lenda da caneta da Nasa se repete…

Um verdadeiro desenvolvedor ágil deve se comprometer com o cliente, ouvir, entender e se envolver com suas necessidades para então sugerir uma solução simples, focada e que resolva o problema. Esta interação é muito importante e deve ser constante, pois o cliente passa a identificar o que realmente ele precisa, ou seja, o qual seu problema! Assim, começa a se concentrar em funcionalidades que realmente serão úteis e agregarão valor ao software e, consequentemente, ao negócio. Feedback é muito importante. O pessoal do Google sabe muito bem disso…

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!?!

A importância de estudar constantemente 3

Posted by Rodrigo Panachi on junho 18, 2008

Já faz tempo que venho ensaiando este post. Minha idéia é mostrar como é importante na nossa profissão de “desenvolvedor” estar constantemente aprendendo novas técnicas, linguagens, frameworks, metodologia, etc. Com um mercado tão competitivo como o de Desenvolvimento de Software, não podemos nos dar o luxo de conhecer apenas uma linguagem. Evidente que é bom que você escolha uma para se especializar, mas de forma alguma deve ser a última linguagem que você aprenderá.

Há algum tempo atrás, orientação a objetos era uma coisa de outro mundo para mim. É sério, não conseguia pensar na possibilidade de existir outro paradigma de programação. Bem, depois que estudei muito sobre OO e passei a utilizar profissionalmente, hoje não consigo me imaginar trabalhando sem OO. Tudo fica claro, organizado, abstraído… O que eu ganhei com isso? Com certeza consegui ser mais produtivo, mais organizado e mais eficiente e, como consequência, melhor remunerado. Se ainda desenvolvesse proceduralmente, certamente ainda desconheceria conceitos e técnicas, sendo apenas mais um na multidão. E não é assim que um verdadeiro desenvolvedor ágil quer ser visto, certo?

Outra coisa que estudei muito e hoje fico feliz em utilizar profissionalmente são Testes Unitários. Uma das premissas do desenvolvimento ágil está relacionada à qualidade do código. Com testes unitários é possível desenvolver incrementalmente e responder rápido às mudanças pois seu código está “protegido”. Além de servir como apoio à refactoring. O que eu ganho com isso? Consigo me preocupar apenas com o desenvolvimento de uma pequena funcionalidade por vez, meu código fica mais “limpo” e manutenível. Em consequencia disto me torno mais ágil e sou melhor remunerado. Além de poder dormir mais tranquilo…

É importante reconhecer que há muito para aprender ainda. Nosso cenário de trabalho muda constantemente e os “usuários” são cada vez mais exigentes. Além disso, é importante lembrar que não existe bala de prata, não existe uma tecnologia que resolve todos os problemas. As linguagens e tecnologias são limitadas e precisam evoluir. Você precisa evoluir junto! Não se esqueça também que lá fora tem um mercado de trabalho começando a enxergar essas qualidades ágeis.

TPW – Dicas para o Desenvolvedor 1

Posted by Roger Leite on junho 04, 2008

Tradução rápida do diálogo:

Chefe (com chifrinhos): Por que você levou seis meses para completar esta simples tarefa ?

Dilbert: Por causa das suas mudanças contínuas, sua comunicação confusa e seu pequeno expediente de trabalho.

Chefe (com chifrinhos): Estou procurando por alguma coisa mais parecida como você sendo preguiçoso.

Hello hello hello ! Estas tirinhas do Dilbert estão de matar ultimamente. E já pra avisar, o TPW significa The Pragmatic Waterfall, um novo termo para o que buscamos aqui neste blog, ajudar quem sofre com o Waterfall ! Ok, isso inclui a mim mesmo.

Quem vive num malditodigno ambiente Waterfall já deve ter vivenciado muito disso que ocorreu acima, o gerente “junior” procurando uma desculpa de porque o gant chart está vermelho para repassar ao gerente “pleno” que este repassará ao “senior junior” e que este repassará “senior pleno” … bom, já entenderam até onde a desculpa vai chegar.

Na tentativa de transformar este post de “muro das lamentações” para Pragmatic Waterfall, vamos as dicas didáticas (ou seria um guia de sobrevivência?) de como tentar contornar este tipo de situação frustante:

==>>Waterfall Model

  • Gerador de código descartável. Sim, é isso mesmo que você leu, o gerador de código você já sabe o que é, agora o descartável é o que você deve estar imaginando. Isso não tem muito a ver com o Waterfall, mas todo projeto que trabalhei tem aquelas camadas que repassam chamadas e seguem um padrão comum. Logo, você não precisa – e nem deve – escrevê-los, para isto inventaram o computador. Se você tem sorte de usar um sistema unix like, se aventure com shell scripts, vale a pena, caso não tenha esta sorte … err, primeiro sinto muito por ti … mas você tem opção de linguagens de scripts como Perl, Python e Ruby em suas mãos, aproveite ! Crie estes scripts descartáveis e gere toneladas de código, seu chefe vai ficar feliz da vida com o aumento da produtividade.
  • Conheça todos os recursos que a sua IDE ou seu editor de texto oferecem. Isso parece ser uma dica besta, mas pode acreditar que não é, já vi muita gente usando um mesmo editor por mais de meses e ficam “abobados” ao descobrirem que o Ctrl+H abre a tela de Replace !!! Bom no meu caso que uso Eclipse o dia todo, as dicas são:
    • Aprenda a usar teclas de atalho, elas realmente aumentam a produtividade. Cheat Sheets como este, ajudam no processo de adaptação.
    • Use e abuse dos Templates, aquelas configurações chatas de xml que toda hora são necessárias, não perca tempo, crie um template para isso e seja feliz. Você pode criar também para aqueles métodos chatos com assinaturas iguais sempre (tipo do Struts mesmo sabe !?!) … o céu é o limite !
    • Aprenda a usar as opções do menu Refactor e – adivinhe! – Geradores de Códigos.
  • Mantenha um checklist de documentos a atualizar, aqueles do tipo, Requisitos, Casos de Uso, Arquitetura, Alteração, Instalação … etc. Com um checklist você não precisa ocupar a cabeça com este passo muito importante do waterfall e lembre-se que neste ambiente o que é valorizado são os documentos e não as pessoas.
  • Antes de começar a sua nova tarefa que está no Gantt, descubra quem são os envolvidos, neste nosso ambiente temos especialistas para todos os lados, converse com eles e feche pactos, pois é muito comum no final da tarefa você descobrir que a procedure retornará um tipo complexo e não um cursor como você imaginava.
  • Sei que isso pode parecer irreal para você que está num waterfall enraízado, porém, tente pelo menos. Tenha um ambiente mock para desenvolvimento, isso pode te salvar ao manter sua tarefa “verdinha” no Gantt Chart. Sim, todos nos sabemos que o Gantt Chart não funciona, porém eu e você que estamos no waterfall temos que usar e até fingir que funciona.

Espero que com essas dicas você consiga se livrar de suas tarefas em menos tempo, e com o tempo que sobrar, aproveite para aprender coisas novas, metodologias novas e descobrir que existe vida fora do waterfall … e acredite ! Estão documentando, aqui, aqui e aqui !