I started searching for a way to express the code in my brain in a simpler, more direct way. I found Ruby and Rails. I felt liberated. Ruby allowed me to express concepts in far fewer lines of code. Rails was so much easier to use than Spring MVC, Hibernate, and the other “streamlined” Java web frameworks. With Ruby and Rails, I got to express a lot more of what was in my head in a shorter period of time. It was similar to the liberation I felt when I moved from C++ to Java...
As my Ruby and Rails projects grew beyond a few thousand lines of code and as I added team members to my projects, the challenges of dynamic languages became apparent.
We were spending more than half our coding time writing tests, and much of the productivity gains we saw were lost in test writing. Most of the tests would have been unnecessary in Java because most of them were geared toward making sure that we’d updated the callers when we refactored code by changing method names or parameter counts. Also, I found that working on teams where there were mind melds between two to four team members, things went well in Ruby, but as we tried to bring new members onto the team, the mental connections were hard to transmit to new team members.
I went looking for a new language and development environment. I was looking for a language that was as expressive as Ruby but as safe and high-performance as Java...
Como você pode ver, grandes desafios no dimensionamento de projetos para o autor acabaram se tornando no desenvolvimento de testes e na transferência de conhecimento.Em particular, o autor detalha mais detalhes explicando as diferenças na escrita de teste entre linguagens tipificadas dinamicamente e estaticamente no capítulo 7. Na seção "Brincadeiras comoventes de Bunnies: Escadas de Dwemthy", discute a porta Scala de um exemplo particular de Ruby:
Compared to the Ruby code, the library parts of the Scala code were more complex. We had to do a lot of work to make sure our types were correct. We had to manually rewrite Creature’s properties in the DupMonster and the CreatureCons classes. This is more work than
method_missing. We also had to do a fair amount of work to support immutability in our Creatures and Weapons.
On the other hand, the result was much more powerful than the Ruby version. If we had to write tests for our Ruby code to test what the Scala compiler assures us of, we’d need a lot more lines of code. For example, we can be sure that our Rabbit could not wield an Axe. To get this assurance in Ruby, we’d have to write a test that makes sure that invoking
|^on a Rabbit fails. Our Scala version ensures that only the Weapons defined for a given Creature can be used by that Creature, something that would require a lot of runtime reflection in Ruby...
A leitura acima pode fazer alguém pensar que, à medida que os projetos crescem ainda mais, a escrita de testes pode se tornar proibitivamente incômoda. Esse raciocínio estaria errado, como evidenciado por exemplos de projetos bem-sucedidos muito grandes mencionados nesta mesma pergunta ("O Python é usado com sucesso para o YouTube").
A coisa é que o dimensionamento dos projetos não é realmente simples. Projetos muito grandes e de longa duração podem "pagar" diferentes processos de desenvolvimento de testes, com suítes de teste de qualidade de produção, equipes de desenvolvimento de testes profissionais e outras coisas pesadas.