terça-feira, 27 de fevereiro de 2007

Você crê em tudo o que vê ?

Você pode dizer qual o degrau mais baixo nesta imagem ?













Continua, continua e nunca termina... :)

Essas e outras ilusões de ótica bem interessantes podem ser conferidas em EyeTricks.
Lá, além das diversas ilusões, há um Gerador Holográfico 3D à venda - mas somente para os EUA. :(

USBs quebrando um galho









Chaveiros e outros dispositivos USB estão virando gadgets cada vez mais bizarros... :)
Veja alguns em Dynamism e Fosfor Gadgets.

sábado, 24 de fevereiro de 2007

Impressão sem tinta

A Xerox está desenvolvendo uma impressora que é capaz de imprimir sem usar tinta. O papel da impressão é reutilizável, podendo ser apagado e reimpresso dezenas de vezes.

Sim, isso pode revolucionar o modo como usamos papel.

Imagine que você acabou de receber um e-mail importante e precisa lê-lo em outro lugar, ou achou um artigo super interessante que desejará ler mais tarde. Você normalmente o imprime, lê e joga o papel fora (ou como eu, guarda o papel e vai colocando numa pilha infindável... ;) ).

Com essa nova tecnologia de impressão, o consumo "desenfreado" de papel pode ser subtamente reduzido. Você simplesmente imprime, lê e depois apaga o papel pra usá-lo outra vez.

O papel especial, por enquanto, permite até 50 reimpressões e o conteúdo impresso apaga entre 16 e 24 horas, quando volta a ficar branco.

Veja mais em TFOT.

Utilitário: Tiny Hexer

 

 

 

 

 

 

 

 

Editor hexadecimal freeware leve e com diversas funcionalidades. Tem editor de disco e de memória, suporte a plug-ins, macros (scripts), unicode, tem atualização automática via web e muito mais.

Confira aqui.

sexta-feira, 23 de fevereiro de 2007

Delphi for PHP ?

A empresa CodeGear, a atual responsável pelo desenvolvimento da nova geração de IDEs da Borland, acaba de lançar duas novas versões do Delphi: a Delphi 2007 for Win32 e a Delphi for PHP. Surpreendentemente nada tem a ver o Delphi for PHP com a linguagem Delphi propriamente dita. Só foi mesmo uma má escolha do nome da ferramenta. (Pessoalmente, acho que "PHP DevStudio" ou algo similar faria mais jus...)
A idéia dela é a de trazer a produtividade da RAD usada pelas outras ferramentas (Delphi, Turbo C++, Turbo Pascal, BDS, etc) para a linguagem PHP.

Quanto a ferramenta em si, essa sim está excelente. A CodeGear trouxe a VCL para o PHP, dando o poder de arrastar e soltar componentes para gerar páginas, conexão com banco de dados e tudo mais. Para desenvolvedores PHP, esta é uma ferramenta de mão cheia.

A CodeGear tem acertado no desenvolvimento das novas IDEs. Estão estáveis e cada vez com melhores recursos. Parece que a Borland fez uma boa jogada passando o desenvolvimento pra ela.

quinta-feira, 22 de fevereiro de 2007

Artigo: As coisas que mais aborrecem no Vista

Uma visão um tanto pragmática sobre os novos recursos do último sistema operacional da Microsoft.

The Most Annoying Things About Windows Vista

(Revista PC World)

sábado, 17 de fevereiro de 2007

Tecnologia para sobrevivência

Ontem à noite, liguei a TV e comecei a passear pelos canais quando vi um japonês falando com tradução em legendas. A imagem cortou para a cena de um chip sendo implantado numa placa e, logo, parei de apertar o "canal +" do controle remoto. Era um alto executivo da Toshiba relatando fatos que ocorreram anos atrás e que foram decisivos para a empresa e para o mundo - principalmente no ramo de eletrônicos. A reportagem, produzida provavelmente no final de 2005, não era sobre a Toshiba ou outra empresa, mas sim sobre a indústria de semicondutores.

Acontece que a japonesa Toshiba revolucionou o mercado há alguns anos atrás com o lançamento de uma SRAM de 1MB, três vezes mais que seus concorrentes. Isso fez com que o domínio do mercado, até então americano, fosse abalado e o Japão despontado como uma das empresas líderes em tecnologia de ponta em equipamentos eletrônicos.

Com o rápido crescimento da Toshiba, diversas empresas buscaram entrar no ramo de semicondutores, sobretudo para a produção de SRAM. Estas empresas, com tecnologia há alguns passos atrás da líder do mercado, começaram a convidar engenheiros envolvidos no projeto da rival para fazer uma visita aos centros de tecnologia - o que "obrigava" os engenheiros a fazer um convite de volta, por questões de educação e ética profissional.

Dentre estas empresas, a sul-coreana Samsung se deu melhor. Convidou o engenheiros da Toshiba à uma visita, ofereceu o triplo do salário, apartamento, carro, empregados, secretária e tudo que um empregado pode receber, e acabou contratando cerca de 70 funcionários da rival.

A Samsung rapidamente cresceu. A Toshiba perdeu a liderança e tempo depois anunciou a interrupção do investimento em semicondutores.

O gerente de projetos da Toshiba, Dr. Fujio Masuoka, que tinha um projeto para uma memória que ele batizou de "Flash" - muito superior à SRAM - acabou indo para uma universidade. A empresa não investia em sua memória Flash pois sua política de lucros era de curto prazo e um investimento deste tipo requeria tempo e recursos.

A Samsung, porém, investiu na Flash e dominou o mercado.

O tempo passou, a Toshiba se reergueu e voltou a brigar.

O ex-gerente de projetos trabalha hoje numa nova memória: a SGT, uma espécie de Flash com armazenamento em 3D. Ele foi convidado por uma empresa da Arábia Saudita e eles irão fazer um investimento milionário nessa tecnologia. Só no novo funcionário foram U$ 82 milhões.

Fim da história, por enquanto.

 

Para o Japão e outros países, uma questão que a nós é quase impensada, para eles é uma obsessão: por esses países não terem recursos naturais, tem que se esforçar em se sobressair inventando soluções e tecnologias que o mundo se interesse e compre.

Acredito que como nós não temos esse problema, não encaramos da mesma forma e por isso também poderemos estar sempre um passo aquém.

Enquanto não mudarmos nossa mentalidade, um investimento público maciço em educação e tecnologia não for feito e estiver essa inconcebível carga de impostos, que engessa o investimento privado, nada poderemos fazer senão comprar - e não fabricar - tecnologia.

Aliás, voltando a falar em memórias Flash, hoje a usamos, compramos, trocamos e elas estão em todo o lugar: celulares, câmeras digitais, mp4 players, etc.

Isso até que, enfim, venha a SGT. Ou mesmo outra (como a MRAM). E, novamente, tenhamos de sucumbir à eficiência e a tecnologia alheia.

Infelizmente nossa "criatividade" não supera nosso atraso tecnológico.

Ciência: Universo com outras dimensões

X (plano horizontal), Y (plano vertical), Z (profundidade), Tempo (sim, a teoria da relatividade geral presente) e........... o que mesmo tem mais ??? ;)

Mais uma teoria interessante e, até agora, sem comprovação:

"Esta é uma das principais candidatas à posição de "teoria do tudo", que os físicos têm procurado como forma para unificar as teorias da Relatividade e Quântica. Só que, até agora, não existe uma forma para se testar experimentalmente essa nova proposta de teoria."

Veja em Inovação Tecnológica.

Site legal: IP-Adress ( com um "d" mesmo )

http://www.ip-adress.com/

Nele é possível você ver a localização do seu IP ou ISP (provedor) num mapa e ainda dar zoom.

terça-feira, 13 de fevereiro de 2007

Utilitário: Launchy

A algum tempo eu havia comentado sobre a linha de software (pago) Enso. Contudo, há uma boa alternativa opensource: o Launchy. Ele tem as mesmas funcionalidades do Enso e apresenta extensões (plug-ins) que lhe conferem talvez o mesmo "poder de fogo" de seu concorrente.

http://launchy.net/

No site há mais skins disponíveis.

Dica C++: Classes sem encrencas

Acompanhe o seguinte código:

 

class Relogio
{
public:
    void Tick() const
    {
        const int UM_SEGUNDO = 1000; // ms
  
        Wait( UM_SEGUNDO );
    }; 
};


class BombaRelogio
{
public:
    BombaRelogio(const int contagemRegressiva)
    {
        _contagemRegressiva = contagemRegressiva;
        _relogio = new Relogio;
    }
 
    ~BombaRelogio()
    {
        delete _relogio;
    }
 
    void Ativar() const
    {
        int contador = _contagemRegressiva;
  
        while ( contador > 0 )
        {
            _relogio->Tick();
   
            contador--;
        }
  
        Boom();
    }
 
    void Boom() const
    { 
        cout << "Boom !" << endl;
    }
 
 
private:
    int _contagemRegressiva;
    Relogio *_relogio;
};

 

A princípio esta classe parece funcionar bem e não haver algum problema:

 

...
{
    BombaRelogio bomba( 10 );

    bomba.Ativar();
}

 

Mas por trás de uma declaração "inocente" como esta se escondem bugs traiçoeiros... ;).

Compiladores C++ foram programados para gerar código por default, quando não deixamos o explícito na classe.

No caso acima, por exemplo, um construtor padrão - sem parâmetros de inicialização - foi automaticamente gerado. Algo como isto:

 

BombaRelogio::BombaRelogio()
{
}

 

Assim, ao criarmos um objeto de BombaRelogio sem passar parâmetros, os atributos não são inicializados, causando erros:

 

...
{
    // Nao instancia _relogio
    // nem inicializa _contagemRegressiva.

    BombaRelogio bomba;

    // Erro de acesso invalido a memoria
    // (tentando acessar _relogio) e loop
    // com duracao arbitraria (por nao se
    // ter conhecimento do valor de
    // _contagemRegressiva.

    bomba.Ativar();

    // Ao destrutor ser executado (no fim
    // deste bloco de codigo) ele ainda
    // tentara' destruir um suposto objeto
    // instanciado em _relogio. Isso causara'
    // mais um erro, ja' que o objeto nao
    // havia sido instanciado.

}

 

Veja quantos erros em tão pouco código...

Uma declaração aparentemente inofensiva causando tantos problemas. Bom, além desses ainda podem haver outros.  O que, por exemplo, se espera de uma atribuição do tipo:

 

BombaRelogio bombaRapida( 5 );
BombaRelogio bombaLenta( 60 );

bombaRapida = bombaLenta;

 

O que, a princípio, se espera é que ao atribuirmos bombaLenta a bombaRapida, a última fique com o valor da contagem regressiva de bombaLenta, certo ?

Bem, isso se esperava...

Como não declaramos um operador de atribuição, o compilador novamente se encarregou de fazê-lo por nós:

 

BombaRelogio& operator = (const BombaRelogio &bomba)
{
    return ( *this );
}

 

E esse operador default não implementa a funcionalidade que desejamos. Assim, a atribuição dos dois objetos não surtirá o efeito que esperamos dela.

O que se pode fazer, então, para que esta classe funcione sem estes tantos problemas ?

Restrinja o que seu código pode fazer.

Ao declarar uma classe, se você quer que ela possa ser construída pelo construtor padrão, declare-o. Senão desabilite-o.

Se você quer que o operador de atribuição funcione da maneira desejada, implemente-o. Senão desabilite-o.

Em C++, para desabilitar um construtor, um operador ou mesmo um método (de ser acessado), basta declará-lo fora da sessão pública.

Lembrando: Se quiser a possibilidade do acesso pelas classes filhas, declare-o como protegido. Senão declare-o como privado.

 

class BombaRelogio
{
public:
    BombaRelogio(const int contagemRegressiva)
    {
        _contagemRegressiva = contagemRegressiva;
        _relogio  = new Relogio;
    }
 
    ~BombaRelogio()
    {
        delete _relogio;
    }
 
    //...

protected:

    BombaRelogio()
    {
        _contagemRegressiva = 0;
        _relogio = new Relogio;
    }
 
 
    BombaRelogio& operator = (
      const BombaRelogio &bomba)
    {
        _contagemRegressiva =
           bomba.ContagemRegressiva;
 
        return ( *this );
    } 
};

 

Declarado assim, como protegido, você impede que um objeto de BombaRelogio possa ser instanciado sem receber a contagem regressiva e também impede de fazer atribuições entre objetos. Caso queira, declare os métodos como públicos.

Com estas simples ações, diversos tipos de problemas podem ser evitados. Portanto, acostume-se a executá-las. ;)

Generalizando:

  • Sempre declare um construtor sem parâmetros (default).
  • Sempre declare um operador de atribuição.

Se você quiser que um ou todos eles não sejam acessados, declare-os fora da parte pública.

 

A declaração de um operador de atribuição público leva à possibilidade de acrescentar à classe um construtor de cópia. Se você pode atribuir os valores de um objeto para outro, que tal você poder construir um objeto que seja um clone de um existente ?

 

BombaRelogio(const BombaRelogio &bomba)
{
    _relogio = new Relogio;
    *this = bomba;
}

 

Declarando mais este simples construtor, você adiciona a possibilidade de clonar objetos existentes:

 

BombaRelogio bombaRapida( 10 );
BombaRelogio bombaLigeira( bombaRapida );

 

Para completar os "requisitos" para uma classe com menos chance de problemas, aproveito para acrescentar este:

Acostume-se a declarar os destrutores como sendo virtuais.

Um destrutor ser virtual (assim como um método) significa que sua implementação pode ser redefinida em uma classe filha.

Acontece que, se você tiver uma classe pai que possua um destrutor não virtual e esse destrutor desaloque alguns objetos da memória, a classe filha terá de fazê-lo denovo. Isso porque o destrutor da classe pai não será executado após o da filha. Isso pode causar muitos problemas, sobretudo por esquecimento ou desconhecimento interno do objeto pai (desconhecimento esse que é até desejável). Sem falar nos casos em que a classe filha não pode nem mesmo acessar esses objetos que precisam ser desalocados, porque não possui acesso aos mesmos - se por exemplo, eles forem privados.

Logo, para evitar esse tipo de problema, sempre declare destrutores como sendo virtuais. Melhor serem e não precisar do que o contrário.

 

Conclusão

  • Restrinja o que seu código pode fazer.
  • Sempre declare um construtor sem parâmetros (default), mesmo que não seja público.
  • Sempre declare um operador de atribuição, mesmo que não seja público. Se for público, declare também um construtor de cópia, que faça uso do mesmo.
  • Sempre declare destrutores como sendo virtuais.

quinta-feira, 1 de fevereiro de 2007

Utilitário: Paint.NET

Nem um Photoshop, nem um Paint. Talvez um meio termo mesmo. Esse "Paint com esteróides" foi desenvolvido para ser leve, simples e intuitivo. E é exatamente assim, mesmo tendo uma boa gama de recursos, como camadas (layers), filtros, desfazer (undo) ilimitado com histórico, efeitos, etc.

 

 

 

 

 

 

 

 

 

 

O Paint.NET é opensource e requer o Microsoft.NET Framework 2.0. Em sua página de download há versões com e sem o framework.