Há alguns meses atrás, eu estava interessado no livro Effective Java, segunda edição. A princípio, eu pretendia comprar na Amazon, mas decidi pesquisar antes. Pela internet, não achei o livro mais barato em nenhum lugar, mas acabei encontrando em uma livraria perto do trabalho por um precinho camarada. Só tinha um problema: era a edição traduzida em português.

Inicialmente nem pensei em comprar a edição traduzida, pois acho que livros técnicos devem ser mantidos na língua original. Algumas pessoas que discordam disto argumentam que nem todos dominam o inglês, mas, sinceramente, se você tem dificuldades com inglês e quer estudar informática, procure um curso de inglês urgente! Por mais que você procure ler somente livros em português, em algum momento vai precisar consultar alguma documentação, referência ou fórum de discussão em inglês. Além disso, acho que nas traduções, por melhores que sejam, acaba-se perdendo um pouco do original (como num filme dublado, em que algumas piadas em inglês perdem completamente o sentido quando traduzidas), aumentando a possibilidade de erros e a dificuldade de compreensão do assunto. Num livro de programação então nem se fala, pois é muito comum utilizarmos muitos termos em inglês que não têm tradução para português - ou até tem, mas o original se popularizou tanto que é usado como se fosse uma palavra do nosso vocabulário.

Na época em que fiz essa pesquisa, o livro estava mais caro na Amazon do que hoje, e ainda tinha que incluir o frete. Aquela edição traduzida sairia por menos da metade. Além disso, eu não teria que esperar a entrega, era só dar um pulo na livraria e comprar. Decidi dar uma folheada no livro, só pra ver se tinha algum erro gritante de tradução, como trechos de código traduzidos - sim, eu já vi livros com aberrações como “calculaMédia”, com acento mesmo. Como não encontrei nada de mais, acabei me deixando levar pela tentação de economizar uns trocados e comprando o livro traduzido.

Quando comecei a ler, achei a tradução muito boa. Nos primeiros capítulos, o único termo que machucou os ouvidos foi “encaixotamento automático” em vez de autoboxing - por mais que esteja correto, esse é um daqueles termos que não se costuma traduzir. Além disso, os trechos de código foram mantidos originais, e abaixo de cada um há a tradução de cada linha de comentário. Achei um pouco desnecessário, porém interessante.

Ao chegar no capítulo 4, estranhamente os comentários nos códigos passaram a ser substituídos pelos traduzidos. Isso continua até o final do livro. Aparentemente a tradução foi feita por pessoas diferentes, e faltou uma revisão mais rigorosa no final. Porém, não é nada que atrapalhe. Mais adiante, vi uma citação a uma referência bibliográfica e resolvi verificar qual era o nome do livro referenciado. Descobri que o livro não tinha bibliografia! Obviamente isso é uma exclusividade da edição em português. Mais uma falha de revisão, e esta é mais grave.

Quando comecei a ler o capítulo 5, que fala sobre generics, achei o trecho abaixo bem estranho:

Antes da versão 1.5, essa teria sido uma declaração de coleção exemplar:

/**
 * Minha coleção de selos. Contém apenas instâncias de Stamp.
 */
private final stamps = ...;

Não está faltando definir o tipo de stamps? Tudo bem, eu não devo ter entendido direito. Sigo a leitura e, um pouco mais à frente aparece o seguinte:

Com os genéricos, você substituiria o comentário por uma declaração de tipo aperfeiçoada para a coleção que passaria ao compilador as informações que anteriormente ficariam ocultas no comentário:

private final stamps = ...;

Ué, mudou alguma coisa? Não é exatamente igual ao código anterior? Resolvi pegar o livro original em inglês emprestado com um amigo, e vejo que nele aparecem os seguintes trechos:

Before release 1.5, this would have been an exemplary collection declaration:

```java // Now a raw collection type - don´t do this!

/**

  • My stamp collection. Contains only Stamp instances. */ private final Collection stamps = … ; ```

e

With generics, you replace the comment with an improved type declaration for the collection that tells the compiler the information that was previously hidden in the comment:

// Parameterized collection type - typesafe
private final <strong>Collection &lt;Stamp&gt;</strong> stamps = ... ;

Os destaques em negrito são do livro original. Aparentemente, tudo o que estava em negrito foi omitido na tradução! E, se estava em negrito, é porque é exatamente o trecho mais importante do código! Posteriormente, descobri que isso acontece em todo o capítulo 5. Do 6 em diante os códigos voltam ao normal e não encontrei mais nenhuma bizarrice, exceto a tradução de “thread” para “segmento”.

Outro erro que se repetiu bastante no livro são as referências a números de páginas (ex: “veja a página 147”). Em todas as situações em que isso ocorre, o número da página que é referenciado é o do livro original, tornando a referência inútil na edição traduzida.

A conclusão que tirei dessa situação: livro técnico traduzido nunca mais! Os trocados que resolvi economizar com o livro acabaram saindo muito caros. Vale muito mais a pena investir um pouco mais no livro original - e num curso de inglês, caso você precise - para não ter dor de cabeça com livros mal traduzidos.


Esta semana saiu o Firefox 3.5, com uma série de melhorias, como o recurso de geolocalização e o modo Private Browsing. Além disso, o browser está muito mais rápido que na versão anterior, devido principalmente ao novo engine de Javascript e ao suporte nativo a JSON.

Além disso, outra novidade importante é a adição de suporte ao HTML 5. Esta versão ainda é um working draft, que traz como principais novidades as tags <video> e <audio>, para suporte nativo a mídias. Assim, não é mais necessário usar tags <embed> e um player externo para a exibição dos já onipresentes vídeos online. Existem vários sites que já utilizam HTML 5 para demonstrar os novos recursos, como mostra este post do Zumo e o Video Bay.


Com a proliferação dos pen drives com alguns GB de capacidade e a preços acessíveis, aplicativos que rodam sem necessitar de instalação tornaram-se igualmente populares. Estes aplicativos “portáteis”, mais conhecidos como Portable Apps, podem ser executados diretamente do pen drive, geralmente com todas as funções dos equivalentes instaláveis. Eles são mais comuns em ambiente Windows (o site mais conhecido é o PortableApps, mas existem outros, como o The Portable Freeware Collection), porém também existem Portable Apps para Mac OS X. Até onde eu sei, não existem Portable Apps para Linux, porém, é possível executar os Portable Apps de Windows via Wine.

Como não poderia deixar de ser, existem também muitos ambientes de desenvolvimento portáteis. Talvez o mais conhecido seja o XAMPP, que inclui um servidor Apache com MySQL, PHP e Perl, entre outras ferramentas. Basta descompactar e executar.

Para Ruby on Rails, também existe um ambiente portátil. É o Instant Rails, infelizmente disponível somente para Windows. A exemplo do XAMPP, basta descompactar um arquivo zip para se ter um ambiente Rails totalmente funcional, com Mongrel, Apache e MySQL. É possível, inclusive, instalar RubyGems e plugins Rails normalmente, como num ambiente Rails comum. O pacote inclui ainda o SQLite, PHP, phpMyAdmin, o editor SciTE e o typo, sobre o qual já escrevi aqui no blog.

A principal desvantagem do Instant Rails é que ele está bastante desatualizado - a versão atual, 2.0, é de dezembro de 2007, e inclui as seguintes versões:

  • Ruby 1.8.6
  • Rails 2.0.2
  • Mongrel 1.1.2
  • RubyGems 1.0.1
  • Rake 0.8.1
  • Apache 1.3.33
  • MySQL 5.0.27
  • SQLite 3.5.4
  • PHP 4.3.10
  • SciTE 1.72
  • phpMyAdmin 2.10.0.2

Segundo o wiki do projeto, há uma petição solicitando o upgrade para a versão 1.9.1 do Ruby.

UPDATE: Só agora vi que o Urubatan escreveu sobre o mesmo assunto no blog dele. Só que ele citou o Ruby on Rails Portable, um projeto muito semelhante ao InstantRails, porém um pouco mais atualizado: a versão do Rails atualmente é 2.1.0 (a do Ruby é 1.8.6).

Outro projeto semelhante que encontrei, mas ainda não testei, é o Flash Rails.


Uma das maiores dificuldades para se aprender JSF é seu aparentemente complexo ciclo de vida, composto por 6 fases. Ao debugar uma aplicação JSF, percebe-se que alguns métodos dos Managed Beans são executados várias vezes, uma em cada fase, o que não é muito intuitivo, principalmente quando se está acostumado com outros frameworks web que utilizam abordagens bem diferentes.

Para facilitar a compreensão do ciclo de vida do JSF, recomendo o tutorial The JSF application lifecycle, da IBM. Ele explica cada fase, e apresenta um exemplo bem simples de uma aplicação usando JSF. Este tutorial é a segunda parte da série “JSF for nonbelievers”. As demais partes também são bem interessantes:


No ano passado trabalhei na Globo.com, e lá tive algumas oportunidades de trabalhar com Scrum (aliás, para quem ainda não leu, recomendo o post do Guilherme Chapiewski sobre a adoção de Scrum na Globo.com). Eu pretendia escrever sobre isso há algum tempo, mas a procrastinação me impedia de transformar um rascunho antigo neste post.

Quando cheguei na empresa, eu não sabia nada sobre Scrum, e fiquei muito curioso ao ver que, em determinado horário, todos os dias, todos os membros de algumas equipes levantavam-se, reuniam-se (em pé!) em torno de um cartaz na parede com vários post-its, e, após 15 minutos, todos retornavam às suas atividades normais. Comecei a observar e estudar o assunto, e aos poucos fui percebendo a simplicidade desta metodologia: tudo o que não for realmente necessário não deve ser feito. Acredito que isto seja um dos principais elementos do Scrum, pois ajuda a manter o foco naquilo que é realmente importante.

Outro ponto importantíssimo, e que é o assunto principal deste post, é o comprometimento. Para que o Scrum realmente funcione, é necessário que o time esteja comprometido com o projeto.

Num dos projetos em que trabalhei com Scrum, o Scrum Master era o Guilherme Chapiewski e o Product Owner, inicialmente, era o Antônio Carlos Silveira. Porém, por falta de tempo disponível para dedicar-se ao projeto, o Antônio saiu do time, repassando o papel de PO para outra pessoa. De todo o time, incluindo o SM e o PO, eu era o único que não estava envolvido em outro projeto. O GC, por exemplo, trabalhava em um outro projeto que era muito maior e mais importante que este, que, consequentemente, tinha baixa prioridade. Desta forma, começamos a passar pelos seguintes problemas:

  • nos Daily Meetings geralmente eu tinha concluído a minha tarefa, e muitas vezes até adiantado alguma outra, enquanto os demais membros do time não tinham nem iniciado as suas, pois estavam muito ocupados com seus outros projetos, e já sabiam que não poderiam iniciá-las nos próximos 2 ou 3 dias;
  • após algumas semanas, começamos a não conseguir mais realizar o Daily Meeting todos os dias, pois não conseguíamos 15 minutos livres de todos os membros do time simultaneamente.

Quando isso começou a acontecer com mais frequencia, começamos, na prática, a parar de usar Scrum, pois já não havia mais comprometimento. Como o Bruno Carvalho já escreveu, Daily Meeting é comprometimento. Não estou dizendo que o time estava desestimulado ou não queria se dedicar ao projeto. Pelo contrário, todos achavam o projeto bem interessante, porém não conseguiam se comprometer a ele, exatamente por estarem comprometidos com outro.

A solução encontrada pelo GC foi pararmos de usar Scrum neste projeto, pois tornou-se impossível praticar Scrum sem que todos os membros estivessem comprometidos. Continuamos a utilizar algumas das práticas do Scrum, como o Planning e o Review, mas na verdade não era Scrum.

A lição que tirei daí foi que é importantíssimo ter um time comprometido com um projeto para que o Scrum realmente aconteça, e que, sem isso, fica muito difícil utilizá-lo na prática. Até acredito que seja possível trabalhar em dois projetos simultâneos com Scrum, mas com certeza exigiria uma grande disciplina para conseguir dividir igualmente o tempo entre os dois, sem deixar de comprometer-se com um ou outro.