segunda-feira, 22 de outubro de 2007

Sem comentários

Hoje deparei-me com o código Javascript seguinte:
function returnFalse()
{
return false;
}

Validação de Strings

É muito frequente encontrar código java semelhante ao seguinte:
if( myStr != null && myStr.equals( "TestString" ) )
{
...
}
Embora o código esteja correcto, é uma pattern recorrente que pode e deve ser simplificada, como na sugestão seguinte:
if( "TestString".equals( myStr ) )
{
...
}
Isto funciona, porque "TestString" existe sempre por ser uma constante (literal), e dado representar um objecto, podemos sempre chamar o metodo equals(...) que por sua vez sabe lidar com o caso de o parâmetro ser null.

Existem ainda situações semelhantes, por exemplo:
if( myStr != null && !myStr.equals( "" ) )
{
...
}
Que podem ser simplificadas de forma a serem mais eficientes, como sugerido a seguir:
if( myStr != null && myStr.length() > 0 )
{
...
}
NOTA: Comparar com a String vazia é menos eficiente, mas se preferirem podem usar a sugestão seguinte, por ser mais concisa.
if( !"".equals( myStr ) )
{
...
}

segunda-feira, 15 de outubro de 2007

Ingenuidade versus desempenho

A ingenuidade de alguns programadores, relativamente à forma como as linguagens funcionam a baixo nível, trás muitas vezes impactos inesperados no desempenho das aplicações.
Vou mostrar um exemplo típico, que se encontra frequentemente em Javascript, uma função que usa um ciclo for para gerar uma lista de valores separados por virgulas.
function getValidZoneList()
{
var zoneList = '';

for( var i=0; i < arrValidZone.length; ++i )
{
if( zoneList == '' )
zoneList = arrValidZone[ i ][ 0 ];
else
zoneList += ', ' + arrValidZone[ i ][ 0 ];
}
return zoneList;
}

O primeiro problema com que nos deparamos é o teste
( zoneList == '' )
, que é tipicamente mais lento que testar
( zoneList.length == 0 )

O segundo problema é fazer testes desnecessários dentro dos ciclos!
Neste caso concreto o teste só é necessário, para determinar se precisamos de adicionar o separador virgula no caso de já termos algum elemento na lista. O facto é que este teste só é relevante no primeiro elemento, sendo falso para todos os restantes.

Se a função fosse implementada da forma que se sugere a seguir, aumentaria significativamente o seu desempenho, pois fariamos apenas um único test, no início:
// returns a comma separated String with the list of Valid Zones
function getValidZoneList()
{
var zoneList = '';

if( arrValidZone.length )
{
var i = 0;
zoneList += arrValidZone[ i ][ 0 ];

for( ++i; i < arrValidZone.length; ++i )
zoneList += ', ' + arrValidZone[ i ][ 0 ];
}
return zoneList;
}

Debug "Artesanal"

Quantos de nos já não fomos forçados ao método de debug "Artesanal", de fazer prints pelo meio do código. À falta de melhor solução, sempre é uma solução, ainda que pobre.

Mas hoje deparei-me com o seguinte, numa tag Body (HTML):
onload="javascript:window.open('about:blank').document.write('<pre>' + document.documentElement.outerHTML.replace(/</g, '<') + '</pre>');"
A ideia desta alma é fazer debug numa janela à parte, atráves de um dump do html/código gerado.
A motivação é clara, pois trata-se de uma página gerada dinâmicamente, e que neste caso inclui geração dinâmica de Javascript, outch!
O "único" problema é que ao fazer isto, qualquer Javascript embutido na página vai deixar de funcionar, dado que todas as variáveis e funções definidas, não o foram, logo vai dar sarna para o "inventor" se coçar, com todas as mensagens de erro que irá receber.

sexta-feira, 12 de outubro de 2007

"Martelar"

O termo "martelar" pertence ao calão informático Português e refere-se ao acto de alterar uma aplicação de uma forma rápida, localizada e sem grandes cuidados estruturais.
Normalmente resulta numa solução suficiente, mas não propriamente ideal, na medida em que não tem em consideração o código circundante ou desenvolvimentos futuros.

Estou a "martelar" o código.

É uma analogia com a profissão de Carpinteiro, mais concretamente ao acto de martelar um prego, supostamente uma actividade que não requer grande destreza ou cuidado, para obter um resultado minimamente satisfatório.

Termos relacionados:
  • "martelanço"
    O acto de "martelar".

    Estou no "martelanço".

  • "martelado"
    O estado final do código depois da intervenção.

    Este código está todo "martelado".

Esta "técnica" é tipicamente usada em situações de urgência/falta de tempo, nomeadamente quando se está em cima dos prazos de término dos projectos, quando já não há tempo para estruturar correctamente o código.

Infelizmente encontram-se com alguma frequência, "Carpinteiros de Software" a tempo inteiro.

quinta-feira, 11 de outubro de 2007

IE 6 window.opener Javascript BUG

Há males que vêm por bem.

Já me aconteceu inumeras vezes ao fazer debug do IE 6 (6.0.2900.2180.xpsp_sp2_gdr.070227-2254) usando o "Microsoft Script Editor (10.0)" determinar que o object window.opener não está definido quando deveria estar, nomeadamente no documento carregado dentro de uma Iframe.
A atitude natural e expectável é culpar o browser (IE), pois já faz tanta coisa mal, que é só mais uma. Assim sendo arranja-se uma forma de circundar o problema.
Mas hoje descobri o cálice dourado :)

O culpado desta vez é o debugger "Microsoft Script Editor".

Se o debugger estiver activo durante a execução de uma instrução que envolva window.opener este objecto não está definido (undefined).

Mas se só chamarmos o debugger depois de executar essa linha, ou simplesmente não lançar o debugger, o código com o window.opener executa sem problemas, pois este encontra-se correctamente definido.

O seja, no caso seguinte window.opener não está definido e dá erro, no debugger:

function GiveZipCode( zipC, cityN, streetN )
{
debugger;
window.opener.fillBoxes( zipC, streetN, cityN );
...
}


desta forma o window.opener JÁ ESTÁ CORRECTAMENTE definido e funciona:

function GiveZipCode( zipC, cityN, streetN)
{
window.opener.fillBoxes( zipC, streetN, cityN );
debugger;
...
}

Para os mais incrédulos, basta chamar o debugger dentro da função fillBoxes() que ele para lá dentro, sem qualquer problema, ou seja conseguiu aceder ao window.opener, logo está definido.

quarta-feira, 10 de outubro de 2007

"Bombar"

O termo "bombar" pertence ao calão informático Português e refere-se ao facto de uma aplicação ou programa estar finalmente a executar sem problemas (conhecidos).

Está a "bombar"


É uma analogia ao funcionamento de uma bomba usada num poço, para extrair água.
Quando está a funcionar existe "output" (água) na saída.