Friday, November 30, 2007

Idéias para posts futuros

So pra não perder a inspiração...

- Sobre o uso de final em atributos, parametros e variaveis locais
- Sobre o uso do "this" em métodos
- Sobre usar ou não construtor em suites JUnit
- Tools de refactor do Eclipse

E como estamos perto do Natal, um pequeno lembrete "by Garfield".


http://www.garfield.com/comics/comics_archives_strip.html?2007-ga071129

--
Otavio Pereira
otaviofp@gmail.com
---------------------------
Programmer (def): An organism that converts caffeine into software.
"Why are we all forced to go to work at the same time? Who arbitrarily decided that 8 AM was a good time for everyone to go to work?" (Dilbert)

Wednesday, November 28, 2007

Sunday, November 25, 2007

Save action on Eclipse

A post in English, for a change. This morning I was configuring my Eclipse workspace to work on my master thesis project and found something interesting. I was not really into working on the project, so I decided to make a small tutorial showing the "save actions" feature from Eclipse 3.3. There probably is some better tutorials out there about this.

Eclipse is a great IDE, and the more I use it, the more I believe in this. Today I came across the save actions feature, new in Eclipse 3.3. Didn't think it would be so great. For a start, you can make Eclipse format and organize your imports after every save. This alone might save the lifespan of some keys in your keyboard, if you are a freak like me that can't write more than a few lines of code without issuing the combo ctrl+shift+f and ctrl+shift+o :). The save actions can be configured in Window -> Preferences -> Java / Editor / Save Actions.

This is the preference page:


After enabling it, you can right away tell Eclipse to format the source code and to organize imports. It'll use your project defaults in every file.

The additions actions section has lots of treasures, and I'll walk trough each one of them. When you click on "Configure" a screen will appear with some tabs, each one for each action category. The leftmost one is Code style that goes very well with the code format options.
Most coders have they own coding style, but when working in a coding team some care must be taken so that the great number of individual coding style doesn't jeopardize productivity. Most companies define their "coding standards" that every single programmer is required to follow.



One of the things that can be enforced by a code style is the use of blocks (or curly brackets) for single-statement control statements. While some might say that not having the brackets reduce the visual complexity of the code, others might say that not having them at all is "bug door" waiting to be open. Whatever is the policy, Eclipse can help enforcing it.

On the "for" side of the things, I'm not really sure if using the enhanced for generates better code at all, but one thing I experienced. It certainly does help in code reading. You see the enhanced for structure, you know that for is iterating over an specific array, the line is shorter than the regular Iterator use. And I also know that going trhough an old Java 1.4 code and converting the fors to the enhanced version is boring. No challenge at all and you just waste some effort time. Why don't let just eclipse handle it by selecting the "Converting for loops to enhanced"? It is pretty smart, but has its limitations.

The following code will not be converted:
for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
Number number = (Number)iterator.next();
/* ... */
}

I can't see a clear reason, but my guess is that it would be just complicated to ensure in a safe way that every iterator use in a raw type list is safe to be converted (someone correct me if I am wrong, but in my tests here this was not converted).

The conversion works for arrays too:
public void method(int[] array)
{
for (int i = 0; i < 2 ="=" 2 ="=">Rename action :). One limitation it has that I can't really see why is that if had you wrote the for increment as ++i instead of i++ the loop wouldn't be converted.

More on the code style, you can tell Eclipse to handle your parenthesis also, by reducing the number of parenthesis, letting him cleanup unnecessary ones, or by summing up a great number of them by always surrounding the expressions.

Another thing it can manage is the existance of the final modifiers. Some like to have private fields that are never modified marked as final. Others say that parameters should never be reassigned, and so on. Eclipse can add final modifiers to private field, paramters and local variables. Just choose your preferred combination :).



A few words on member access rules. It's possible to have Eclipse to policy your use of the qualifier to non-static members. Some programmers like to have all non-static members qualified with a this, others avoid having this at all (by naming non-static fields with a leading or trailing _, or with some prefix such a 'm', etc), and others just like to have the this when it is necessary. If you are on the latter 2 groups, tell Eclipse to just use this when necessary, or if you are in the first, let him ensure every access is qualified by this. Works for methods and fields.

You can as easily let Eclipse handle your access to static members, by qualifying field or method accesses so every static access will have the class qualifier even in the declaring class. You can also let it change static access through subtypes (for instance, using a member of IResource from an IFile class), or through instances (using a member from IResource from your local variable instance). Eclipse can be programmed to show compiler warnings for those 2 items, but isn't it just better to just have him solve the problems?



During the lifecycle of a source code, many members will be introduced, some other will be removed, and some will just loose the purpouse but will be left unremoved because the programmer didn't see them. This is another situation that ever since I can remember Eclipse is good in warning us, but now he just be configured to solve the problem by himself by removing unused imports, removing unused private members or unused local variables. Just let him remove the garbage. Casts and $NON-NLS$ tags can also be automatically cleaned up.


But wait! Eclipse is not just powerful to remove code, he can also insert some stuff. But, it's easier to destroy than to construct, so the options to insert code are just a few, yet they are useful. You can let Eclipse ensure that every overriding method has its @Override annotation, so if for some reason the original method is removed it is just easier to figure out that the code won't work (it'll not even compile, to be honest).
Eclipse can insert the new @Deprecated annotation to members or classes that carry the old @deprecated javadoc tag.



And in the very end, you can have Eclipse doing some code organization for you. If you have strict policies over trailing whitespaces (you know, that extra whitespace that the IDE inserted when you decided to add that extra blank line before the method by placing the cursor just before the declaration and not on the first column), you can let Eclipse wipe them, or wipe them only if the line is empty, or leaving them alone. The choice is all yours.

And another little help Eclipse can do is if you have policy for member ordering, such as "place all your constructors togheter, after the fields" and so on. You can have Eclipse applying the "Sort members" action in every save, so you can guarantee the members are ordered.

You could've figured out just about everything I wrote here, but hey, I had a sunday to waste ;).

Tetris

Pra comceçar bem o domingo... acho que não tem ninguém no mundo que não conhece tetris. Eu sempre achei que ele era um jogo sem fim, que depois de cada nível sempre teria um próximo até que a velocidade do computador superasse a do jogador. Bom, tem um japonês (tinha que ser! =oP) que me mostrou em 6:23 (6 minutos e 23 segundos, e não 6 horas!!!) que pelo menos em um tetris específico o "Master mode" tem fim. Alias, eu tenho a leve impressão que ele trapaceou, ele sabia a seqüência de peças antes do jogo... o final do vídeo me deu essa impressão. Sem mais spoilers, sorte minha que eu tava sentado quando vi isso, assim meu queixo só da altura do pescoço até as pernas.



Artigo original: http://www.gamesradar.com/us/pc/game/news/article.jsp?articleId=200711239291393082&releaseId=2006032219817514003§ionId=1006&pageId=20071123103336234046

PS: A teoria dos cyborgs parece fazer sentido...

Friday, November 23, 2007

Aventuras com JUnit

Bom, hoje aconteceram 2 eventos importantes que levaram a esse post, um deles foi a Thânia, software developer na minha equipe, me colocar na cabeça a idéia de que seria uma boa coisa eu fazer um blog - portanto, já sabem uma das culpadas desse blog existir - a outra culpada eu aponto em um momento futuro ;). O outro evento foi uma pergunta que a Thânia me fez. O cenário, descrito em um post dela, é resumido em: eu inicializava alguns atributos da suite de testes em um método @Before, agora cheguei a conclusão que esses atributos devem ser inicializados apenas 1 vez para todos os testes. A solução que ela relutantemente aceitou é mover a inicialização para um método @BeforeClass, e transformar os atributos em static (pois todo método @BeforeClass deve ser static, e não é possível acessar atributos não static em um método static, bom, pelo menos não de modo simples e direto no código). Depois vi o post no blog dela falando sobre isso, e como ela não tinha aceitado muito bem, resolvi ir atrás e descobrir algumas razões para fazer desse jeito.

A primeira coisa que eu fui ver foi a FAQ do JUnit, onde encontrei uma pergunta falando sobre os @BeforeClass e @AfterClass, e nessa pergunta, eles basicamente diziam que @BeforeClass e @AfterClass são do lado negro da força, e normalmente indicam um problema. Bom, o fato é que as vezes eles são um mal necessário, por exemplo, quando os testes dependem fortemente de algum recurso caro para ser inicializado, como uma conexão a um banco de dados, ou algo do gênero. Não vou entrar no mérito de se o caso dela é um indicativo de problema ou não, mas sim levar o foco à pergunta não bem respondida: por que fazer os atributos virarem static ao invés de usar inicialização em um construtor ou na declaração.

Entre as duas últimas opções, pessoalmente prefiro a opção do construtor. Fica a promessa de um novo post sobre isso. Mas independente disso, as duas são equivalentes. Então a pergunta se resume a: tornar static ou manter como atributos de instância. Quando respondi pra ela me ocorreu uma primeira ideia para justificar a transformação para static: execução paralela dos testes. Isso não foi suficiente pra convencê-la, e para falar a verdade, nem eu acredito mais nisso. A outra justificativa para ela surgiu depois uma busca nos meus arquivos de memória por alguma coisa na documentação do JUnit que garantisse que cada suite seria instanciada uma única vez. Não achei. E isso para mim já é motivo suficiente para adotar a alternativa mais segura. Resolvi pesquisar um pouco mais sobre isso quando cheguei em casa, mas optei dessa vez por um método "hands on". Montei alguns cenários e mandei rodar o JUnit. Basicamente, fiz testes com System.out.println() em vários momentos do ciclo de vida de um teste JUnit. Inicializadores static, métodos @BeforeClass e @AfterClass, métodos @Before e @After, inicializadores regulares, métodos @Test, e depois usei herança entre testes, para ver como a coisa se comportaria.

Mandei rodar, e estava quase pensando em o que mais procurar para justificar a transformação em static, achando que eu veria a saída dos inicializadores somente antes do primeiro @Before. No entanto, o que eu vi foi: o JUnit cria uma nova instancia da suite para cada teste, portando, colocar código em construtor ou em inicializadores não-static é a mesma coisa que definir eles em um método @Before, que era a solução anterior e por algum motivo deixou de ser adequada.
Não fui na documentação do JUnit buscar se isso tem alguma explicação ou foi simplesmente decisão de projeto. Parece fazer sentido do ponto de vista de independência de testes essa decisão, dessa forma, o framework dá uma mãozinha para evitar que um teste influencie no resultado de outro.

That's all, folks!

Hello, world!

Bom, todo programador que começou com uma nova linguagem de programação ou tecnologia já fez um "Hello, world!", a pedra fundamental do mundo da computação. Então, já que estou começando aqui, nada melhor que um hello world para ver como a coisa se comporta =).

Bom, vamos ver quanto tempo eu duro com esse blog =oP. Não vou me restringir a um assunto específico (apesar de que acho que é isso que faz um blog de sucesso, mas quem quer sucesso já na primeira vez?!).

Boa sorte!