segunda-feira, 21 de maio de 2007

Apresentando dados tabulares com estilo

Olá a todos mais uma vez.

Você costuma usar tabelas HTML? Você já precisou usar uma tabela HTML para mostrar dados de um banco de dados? Você (ou seu usuário) alguma vez já se confundiu com as linhas nos dados tabulares?

Bem, acho que a resposta da maioria a todas as perguntas é sim. Vamos abordar a última pergunta.

Para não haver confusões entre as linhas nós temos diversas soluções:

- Bordas na tabela: Esta é a mais fácil de se implementar e o mais básico: É só colocar o atributo border="1" na tag <Table>. Com os estilos CSS podemos colocar até bordas mais bonitas. É legal, é fácil, mas não é muito sofisticado - porém não subestime - às vezes menos é mais.


- Estilo "zebra": Cada linha de uma cor diferente, alternando entre duas cores. Uma solução bem bacana. Quando a tabela é dinâmica é bem fácil de fazer:

<table>
<tr>
<th>Título</th>
</tr>
<?
foreach ($resutset as $registro) {
$cor = ($cor == "#ffffff" ? "#eaeaea" : "#ffffff");
echo "<tr style='background: $cor'>";
..
..
echo "</tr>";
}
?>
</table>



- DHTML: Todas as linhas têm o mesmo fundo, mas a linha atual muda de cor quando o usuário passa o mouse sobre ela. Exemplo:

<table>
<tr>
<th>Título</th>
</tr>
<?
foreach ($resutset as $registro) {
?>
<tr onmouseover="this.style.background = '#eaeaea'"
onmouseout="this.style.background = 'none'">
...
...
...
</tr>
<?
}
?>
</table>


Assim também fica muito legal.

Este assunto pode parecer bobo, mas às vezes são coisas pequenas assim que definem a identidade de um site ou de uma aplicação web, levando ao seu sucesso.

Grande abraço a todos e até a próxima!

Artigo completo (View Full Post)

terça-feira, 15 de maio de 2007

Windows - Chick Corea

Vou tocar com amigos!!!! O Outro Windows na minha vida .... hehhehh





Windows, com certeza não é o tema dos mais freqüentes nas raras e remanescentes Jam Sessions que nos dias de hoje poucos privilegiados têm acesso. Também não é uma obra nova, nem desconhecida dos jazzistas. Muito pelo contrário, tenho observado que é uma composição que agrada a maioria dos músicos.
Não é um exagero de complexidade, mas também não é um blues em 12. É uma música que lava o instrumentista para além da fronteira do trivial oferecendo uma gama soluções não convencionais. Seu aspecto rítmico contribui nesse sentido, visto que a sub-divisão em três favorece e fortalece a predominância de uma riqueza de detalhes analogicamente variantes. Bem, pra mim esta entre os top 20 melhores temas de todos os tempos (hehehehe ...).

Artigo completo (View Full Post)

segunda-feira, 14 de maio de 2007

Tela Azul - STOP:C0000218{Falha no arquivo do Registro}

Tive uma surpresinha quando fui ligar o micro hoje, ao iniciar o windows entrava numa tela azul com a singela mensagem:

STOP:C0000218{Falha no arquivo do Registro}
O registro não pode carregar a ramificação (arquivo):
\systemroot\system32\config\software
Ele está corrompido, ausente ou não pode ser gravado.

O HD onde está instalado esse SO está barulhento demais, é muito provável que o arquivo tenha corrompido. A tradicional e rápida busca na Web ... de cara encontrei uma dica para usar um verificador de disco, tipo DiskDoctor, ou o do próprio Windows. Como eu tenho mais de um SO nesta máq, assim o fiz. Inicializei pelo pelo SO bom, em ferramentas administrativas ▶ Gerenciamento do Computador ▶ Gerenciamento de Disco:



Botão direito sobre o HD com problemas (em caso de duvidada repita em todos), selecione propriedades ....


Em verificação de erros, click no botão “Verificar Agora”. Marque as duas opções (Corrigir erros e procurar setores defeituosos), em seguida click em “iniciar”.


No meu caso isso foi suficiente, problema resolvido! Agora, caso você não tenha um outro SO de opção pode ser que seja necessário usar o CD de instalação do Windows. A busca que fiz no Google retornou muitas ocorrências desse problema no XP, ao que parece esse problema é bem comum.

Segue o procedimento para reparação do SO via CD de instalação:

Antes de partir para a FORMATAÇÃO, vc pode tentar usar o console de restauração do WINDOWS. Com ele você poderá usar linhas de comando para iniciar ferramentas de recuperação, iniciar e parar serviços, acessar arquivos no HD, substituir arquivos corrompidos do sistema, etc. O Console de Recuperação é acessado através do CD de instalação do Windows.
Para ter acesso a ele você deve dar boot no sistema com o CD do Windows. Se o setup do computador estiver configurado para dar boot inicialmente pelo drive de CD-Rom, basta inserir o CD e reiniciar o computador. Após o boot pelo CD, pressione alguma tecla para iniciar a instalação do Windows. Em seguida a tela de “Bem-vindo”, pressione a tecla R para reparar uma instalação do Windows XP. Um menu listará uma, ou mais instalações do Windows no HD, digite o número relativo ao Windows que você deseja recuperar e
pressione “Enter”. Caso exista senha, surgirá o prompt para que você entre com o login de Administrador. Em seguida, aparece o console de recuperação. Siga os passos:
1º digite o número correpondente ao HD que será recuperado
2º senha, se houver
3º digite - cd system32
4º digite - cd config
5º digite - ren system system.old
6º digite - copy c:\windows\repair\system
7º digite - exit

Após a reinicialização o windows deverá estar recuperado.
Para quem quiser pesquisar mais, veja em: Suporte MS.
Pode ser útil tb um tutorial.

Artigo completo (View Full Post)

domingo, 13 de maio de 2007

Private, Public, Published ... Escopo de visibilidade

Um conceito muito importante do paradigma OO é o encapsulamento. Ele define a visibilidade dos membros de uma classe. Cabe lembrar que esse conceito não é exclusivo da orientação a objetos. A preocupação com o escopo e visibilidade, já na estruturação era uma questão extremamente relevante. Na verdade, uma das razões de ser da estruturação é justamente uma adequação melhor da questão da visibilidade. Que tinha na organização modular, conjugada com os conceitos de coesão e acoplamento, a representação lógica dos seus princípios.
Eu costumo “dramatizar” para meus alunos, como recurso didático, que a orientação a objetos, com relação ao encapsulamento, não propôs nada de novo. Não menos importante por isso, o que ela faz é simplesmente pegar esse conceito e leva-lo as últimas conseqüências. Aperfeiçoando, na minha opinião, o que já havia sido proposto pela Teoria Geral de Sistemas. Um sistema é sempre um subsistema de um outro em nível hierárquico mais alto (isso me lembra o final do filme MIB... hehehe ... mas sem cao, isso é importante). Amigo, isso era vanguarda no império do Cobol! Se liga!!!! Entretanto, ainda hoje, parece, e não sou eu o único a falar sobre isso, que a ficha ainda não caiu. Eu estou cansado de ver programas em Java que começam com um “public static void main(String args[])”, dentro dele vc pode encontrar de tudo, parece até a bolsa do “gato felix”. Na mesma e única classe você encontra desde

public static Connection getConnection()
throws ClassNotFoundException, SQLException {
String connectStr = "jdbc:odbc:BancoDoido ";

String username = "";
String password = "";
if (c == null) {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
c = DriverManager.getConnection(connectStr);
}
return c;
}


até comando SQL .... creeedooo!!!!

public void cadastar(dado1, dado2, ... dadoN)
{
‘Insert into ......’
}

public void alterar(dado1, dado2, ... dadoN)
{
‘Update tabela set......’
}

public void excluir(dado)
{
‘Delete from tabela where ....’
}


Isso não é um problema RESTRITO a uma tecnologia específica, seja em Delphi, VB, ASP, passando pelo PHP ao C++, observamos recorrentemente essa falha. Com um agravante, hoje é grande a parcela dos programadores, que a pesar de freqüentarem, desde a graduação as pós e MBAs da vida, aulas de AOO e POO, justificarem (com a maior cara de pau) a modularização digamos pouco ortodoxa, para não dizer porca, de seus sistemas, que por uma questão de produtividade assim o fazem. Respaldados por um reducionismo digno da mais pura filosofia de botequim, cujo o genial objeto de argumentação é sustentado pela cínica pergunta retórica: “Até que ponto não perderemos produtividade ... nos abstendo do “rococó Bizonho”?”. Os açougueiros de toga com seu objetos perfurocortantes assassinam Yourdon, Page Jones, Chris Gane, Pressman e est ... até o Tanenbaum sai decepado nesse cenário Tarantiniano patético.
Então ... voltando ao assunto ... Por isso, justamente para possibilitar ao programador/analista uma opção dele não ser lembrado como exímio representante do estilo rococó bizonho D’Mono Neurônio, existe o encapsulamento. Que, por sua vez, para ser feito de forma adequada deve seguir harmoniosamente o conceito de escopo de visibilidade.
Entretanto, existe um porém, infelizmente você não tem uma fórmula para se construir classes, ou módulos, que equacionem esse conceito perfeitamente, sob um ponto de vista absoluto. Nenhuma heurística de encpasulamento vai ser garantida de nada, porque em última análise quem vai definir o que vai ficar visível, ou não, é você. Portanto, alcançar um grau satisfatório de coesão dos seus módulos depende, em parte (uma boa parte, na minha opnião), de bom senso. Em contrapartida, a boa notícia é que a outra parte depende de você entender bem as definições que veremos a seguir:

Primeiro, leia o artigo que o Felipe escreveu sobre isso, em seguida volte.
Uma regra básica, que ajuda bastante: A interface de cada módulo, ou para cada módulo, deve ser definida de forma que não revele nada sobre o funcionamento do mesmo. A velha idéia de caixa preta. O Exemplo que o Felipe colocou sobre a televisão foi show!

Quando estamos especificamente definindo uma classe, podemos entender encapsulamento como a forma de se harmonizar os membros dessa classe, ou seja, os atributos, dados da classe, e as funções, operações que serão feitas sobre esses dados. Sobre uma definição que oculte, eficientemente, os detalhes dessa implementação. Lembre-se da “caixa preta”.

Em Delphi language, as palavras chaves que definem o escopo de visibilidade dos membros da classe, na seção delimitada por elas. Vejamos:

  • Private – Visibilidade exclusiva a própria classe. Tudo que estiver declarado na seção private da classe o escopo de visibilidade estará restrito a própria classe. Nem mesmo a instância enxerga.
  • Protected – Tudo que estiver declarado em protected o escopo de visibilidade estará restrito somente a própria classe e aos seus descendentes. Ou seja, somente a própria classe e as que estenderem dela conseguem acessar o que esta definido em protected.
  • Public – Nenhuma restrição de visibilidade. Conforme o próprio significado da palvra chave, público, indica que todos tem acesso ao que estiver definido ali.
  • Published – Visibilidade idêntica ao escopo definido pela public. Ou seja visibilidade irrestrita. O que difere uma da outra é que o Delphi gera RTTI para os membros definidos dentro do escopo dessa seção. Por isso esses membros podem ser listados pelo Object Inpector e serem acessados em design-time.
  • Automated – Mesma visibilidade dos membros public, com uma característica: Informação se automação é gerada para os membros nela declarados. É mantida por questões de compatibilidade com versões anteriores. Infromações de automação é pertinente a API OLE Automation.

Até aqui tudo bem? Quase! Seria perfeito se não fosse um probleminha. Existe um conceito em OO sobre classes amigas, que cada linguagem de programação deu suporte a ele de forma diferente. No Delphi, a Borland, na época, implementou da seguinte forma: Não há restrição se visibilidade para classes definidas na mesma unit. Na prática isso joga todo o discurso sobre encapsulamento por água abaixo.
Só que o homem evolui, o mundo evolui e a Borland também evoluiu. Por conta do frame work .Net, a Borland teve que, para manter compatibilidade com a CLS (Common Language Specification) da .Net, introduzir dois escopos novos: Strict private e Strict protected. Eles podem ser usados também em aplicações win32 e fazem rigorosamente o que o private e o protected não fazem. Eles acabam com a visibilidade das classes amigas. Os membros declarados dentro do escopo de strict private possuem visibilidade restrita a classe mesmo para as classes definidas na mesma unit. O mesmo para strict protected, os membros declarados nela somente são acessíveis a própria classe e aos seus descendentes.

O objetivo do encapsulamento é o ocultamento de informações específicas. De que forma podemos fazer isso? Restringindo o escopo, restringindo a visibilidade. Qual o objetivo disso? Conseguir um isolamento das funcionalidades de um determinado módulo, de maneira que o entendimento (legibilidade) seja fácil, a manutenção também seja pouco custosa (não reflita para outros módulos). Atingindo esse grau de isolamento esse módulo poderá ser reutilizado. Portanto, concluindo, o encapsulamento traz, imediatamente, para o desenvolvedor três vantagens ao ser empregado: Fácil entendimento, maior manutenibilidade e reuso. Voltando ao exemplo da Tv, quando vc for comprar um aparelho novo, pouco vai importar a tecnologia empregada no produto. Seja plasma, LCD, ou sei lá o que, o usabilidade dos controles remotos são quase que padronizadas. Por isso você vai confiante comprar o produto sabendo que sem o menor problema, em poucos minutos você estará assistido seu programa favorito.

Pra finalizar, a maior e mais aprazível vantagem de você dedicar o devido cuidado com encapsulamento nos seus programas é, por exemplo: num conturbado dia 23 de dezembro, às 15:00, às margens do dead line, terminar o módulo previsto e de repente, involuntariamente, escapar em voz alta: “Pronto!!! Está funcionando!! Eu amo isso!!!!”. Duvido, e faço pouco, se o adepto do rococó bizonho D’Mono Neurônio é capaz da mesma coisa.


Artigo completo (View Full Post)

quarta-feira, 9 de maio de 2007

Estendendo a funcionalidade do tipo String

Olá a todos.

Vamos falar um pouco sobre javascript.

Conhece o tipo String. Já sentiu falta alguma vez de algum recurso que o tipo não dispõe? Eu já; e um exemplo na cara é o trim (aquele que retira os espaços das extremidades).

Incrível o javascript não ter, não é... Mas tem uma coisa incrível que o javascript tem, que é a possibilidade de estender a funcionalidade de qualquer classe e tipo de dados.

Cada elemento tem uma propriedade chamada prototype, que nos permite a definição de novos métodos da classe.

Vou mostrar como eu fiz minha extensão da classe String:


primeiro vamos criar o trimLeft - que retira todos os espaços à esquerda da string:

String.prototype.trimLeft = function() { return this.replace(/\s*((\S+\s*)*)/, "$1"); };


Agora o trimRight - retira os espaços à direita:

String.prototype.trimRight = function() { return this.replace(/((\s*\S+)*)\s*/, "$1"); };


Por fim, usando os dois, o método trim, que 'capa' a string:

String.prototype.trim = function() { return this.trimLeft().trimRight(); };


Legal! Legal! Legal! Eh..... como é que usa? Eu tentei trim(variavel) mas não funcionou...

Agora vamos à parte mais legal da parada: como o método foi definido para o tipo String, todas as instâncias de String possuem estes três novos métodos:

var variavel = " Olá ";
var var1 = variavel.trimLeft(); // var1 é "Olá "
var var2 = variavel.trimRight(); // var2 é " Olá"
var var3 = variavel.trim(); // var3 é "Olá"

Maneeeeeeeeiro...

Assim como o tipo string é possível estender qualquer tipo de dados em javascript adicionando funcionalidades através do membro prototype. Solte a imaginação e faça bom uso!

Grande abraço a todos e até a próxima!

Artigo completo (View Full Post)

domingo, 6 de maio de 2007

Comentando linhas de código

Saber fazer uso de comentários em seus programas pode trazer um ganho de produtividade significativo nos seus projetos. Definir um POP (procedimento operacional padrão) que formalize a utilização de comentários para auto-documentação dos módulos implementados é uma prática fundamental adotada pelas equipes de desenvolvimento, fabricas, houses, de software sérias.
Em contra partida, usar comentários para manutenção de lixo, código de teste, código errado, e desatualizado, nos seus fontes é totalmente condenável. Alias, é exatamente isso que acontece quando não se adota uma pratica formalizada para o emprego de comentários.

No Delphi existem alguns tipos de comentários, vejamos:

“//” Barra – barra: comenta uma linha apenas. Exemplo:

procedure TForm1.Edit1Click(Sender: TObject);
begin
// esse código será executado se vc clickar no Edit1

Form1.Caption := (Sender as TEdit).Text;
// A linha de código abaixo está comentada
//Form1.Color := (Sender as TEdit).Color;
end;

Continua ....

“{}” Chaves: Comenta um bloco de código. Ou seja, comentário de várias linhas. Exemplo:

procedure TForm1.FormClick(Sender: TObject);
begin
{Esse código será executado se o Form1 for clickado.
Observe que neste exemplo eu posso comentar mais de uma linha
usando as chaves. }
if Form1.Height > 100 then
Form1.Height := Form1.Height - 20;
ShowMessage('Vc clickou no Form1!! BHUAHAUHA ...');
end;

“(**)” Parêntese + asterístico: Comenta um bloco de código. Ou seja, comentário de várias linhas. Exemplo:

procedure TForm1.FormResize(Sender: TObject);
const
msgZn = 'O %s foi redimencionado: Altura - %d; Largura - %d';
begin
(*Esse código será executado cada vêz que
o Form1 for dimencionado. Observe que neste
exemplo eu posso comentar mais de uma linha
usando Parêntese + asterístico. *)
ShowMessage(Format(msgZn, [Form1.Name, Form1.Height, Form1.Width]));
end;


Qual a diferença entre os comentários de bloco, de mais de uma linha (várias linhas)? Por que eu preciso ter dois tipos diferentes de comentários diferentes que fazem exatamente a mesma coisa? Para que vc possa aninhar comentários. Não é possível aninhar comentários do mesmo tipo. Exemplo:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
{ Esse exemplo mostra como comentários podem ser aninhados
A := B; Creeeeeedddooooooo
// comentei uma linha ...
}

(*
{ eu ai fazer este código assim...
Form1.Caption := Key;
Mas, mudei de idéia ...
}
Mais comentários ... *)

Form1.Caption := Form1.Caption + Key;
end;


OBS: Lembrando, qualquer coisa que pareça um comentário, mas começa com o caracter “$” (dollar), não é um comentário. É uma diretiva de compilação.

Novidade importante e interessante

O BDS possui suporte aos comentários para documentação “XML”. O Delphi extrai esses comentários da sua unit e salva como XML. A mesma lógica vigente para os comentários anteriormente exemplificados, vale para os seus respectivos comentário para documentação XML.

/// - Comentário de uma única linha.
(*! *) - Comenta um bloco de código. Ou seja, comentário de várias linhas.
{!} - Comenta um bloco de código. Ou seja, comentário de várias linhas.


type
/// Esse é o Form1 - este é um comentário para documentação XML.
TForm1 = class(TForm)
Edit1: TEdit;
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure FormResize(Sender: TObject);
procedure FormClick(Sender: TObject);
(*! Neste artigo estamos abordando comentários na unit de código.
Estamos testando também a nova funcionalidade de documentação do BDS.
!*)
procedure Edit1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

O BDS possui uma funcionalidade de documentação das units. Essa funcionalidade é ativada nas opções de projeto: Menu Projetc ► Options ► No item da treeview ► Compiler, em documentation, marque a checkbox “Generate XML documentation”.



Agora, faça um rebuild da aplicação: Menu Projetc ► Build Project (Shift +F9). Veja no diretório onde você salvou o exemplo, dois arquivos novos: “Unit1.xml” e “project1.xml”.



Esse XML pode ser processado por ferramentas que geram documentação nos mais diversos formatos. Além disso, o conteúdo desse arquivo pode ser consumido pelo help do Delphi.



O Doc-O-Matic, por exemplo, é uma excelente ferramenta para gerar documentação a qual poderia ser usada para consumir o XML gerado pelo Delphi para ducumetação.


Ah! Falando em Doc-O-Matic, lembrei de um lance: O comentário para documentação tem que ser feito em áreas específicas da unit. Lembrei disso porque no Doc-O-Matic também funciona dessa forma. Durante a composição dos exemplos para esse artigo percebi que o Delphi não considerou o comentário que fiz dentro do procedimento. Após um breve momento de indignação, lembrei que no Doc-O-Matic os comentários a respeito de métodos, funções e procedimentos deveriam ficar exatamente na linha superior ao corpo do procedimento. Exemplo:

{! Comentário para documentação XML deve ficar aqui! Este é o evento OnClick do Form1}
procedure TForm1.FormClick(Sender: TObject);
begin
{Esse código será executado se o Form1 for clickado.
Observe que neste exemplo eu posso comentar mais de uma linha
usando as chaves. Ess comentário não vai para o XML ...}
if Form1.Height > 100 then
Form1.Height := Form1.Height - 20;
ShowMessage('Vc clickou no Form1!! BHUAHAUHA ...');
end;



Artigo completo (View Full Post)

sábado, 5 de maio de 2007

Que saudade do Tetris...

Olá a todos os amigos.

Eu não sou músico, mas adoro música. E Adoro jogos eletrônicos também. Assim como eu, existem milhares por aí (Gerson?)

Lembram do Tetris? Esse é da antiga! Eu adorava jogar naqueles minigames doidos...

Agora vem a parte legal. Nesse vídeo Tem uns caras que tocam a música do Tetris no violão! E tem um fazendo a base e outro o solo. Cara, simplesmente louco.
Edit: É o mesmo cara fazendo os dois! Ainda rolou uma edição e montagem maneiras na parada! Hehe...

Abraços a todos e até a próxima.

Artigo completo (View Full Post)

TypeCast e operadores da RTTI

Um recurso que possibilita extrema flexibilização de módulos implementados.

Considero técnica avançada a utilização de typecast, não pela sintaxe ou aplicabilidade do conceito, mas sim, porque na maioria das vazes que um módulo desenvolvido pretende ser mais abstrato, mais genérico, conseqüentemente, por isso, adaptável a diversas situações, implica num custo para sua construção de um grau de complexidade muito maior. E não são poucas as vezes que na implementação de um módulo com essas características seja imprescindível a utilização de typecast.
Na busca de desenvolver módulos flexíveis, freqüentemente o programador escreve em seu código atribuição de valores, ou recuperação deles, a partir de um conhecimento prévio que ele possui, mas o compilador não. Essa não é uma situação muito segura e podem ocorrer problemas, podem ocorre exceções. Inclusive, permita-me um parêntese, falamos sobre esses problemas no artigo sobre exceções, especificamente, exceções de typecast.
Obter informações sobre a herança dos objetos em tempo de execução, também é feito através dessa técnica. Alias, o grande “x” da questão aqui é justamente é obter informação sobre os objetos em run time. O Delphi possui um “mecanismo” para se obter in formações de tipos em tempo de execução, runtime type information (RTTI).


RTTI

O runtime type information, permite que a IDE possa gerar, automaticamente, informações para o desenvolvedor em disign-time sobre um série de coisas. Por exemplo, quando o desenvolvedor “experimenta” o reflexo da manipulação das propriedades dos componentes visuais em tempo de projeto. Podemos tirar vantagens desse mecanismo também para nossas implementações. Entretanto, o emprego dessa técnica não é nada obvia de como se empregar, visto que, na própria documentação do Delphi não encontramos muita coisa sobre isso.
Quando estamos construindo um form, os componentes que adicionamos a ele (depositamos), são automaticamente declarados no topo da definição da classe do from e as propriedades e eventos desses componentes são listados no Object Inpector. A RTTI, faz com que tudo, da definição de uma classe, que estiver declarado na seção pubished produza esse comportamento na IDE.
Note também que quando alteramos os valores default das propriedades dos objetos, essas alterações são persistidas no arquivo .dfm. Dessa forma em tempo de execução seu form é construído exatamente como vc projetou.


O que é Typecast?

Tratar um valor, ou variável de um tipo como se fosse outro tipo. Como? Ficou doido? Não estou doido não, isso é possível. Veja:


procedure TForm1.Button1Click(Sender: TObject);
const
msg = '%d';
MsgS = '%s';
var
vBoolean: Boolean;
begin

(* recupera o resultado da expressão lógica,
relacionando os correspondentes valores inteiros a cada um dos
caracteres ASCII, “A” e “\”.*)
vBoolean := word('A') < Integer('\');

(*exibe o valor inteiro correspondente ao caracter ‘/’ nas tabela ASCII *)
ShowMessage(Format(msg,[Integer('/')]));

(* Atribui ao caption do form o caracter d tabela ASCII, cujo o valor inteiro é 65 *)
Self.Caption := Format(MsgS, [Char(65)]);

(*Atribui ao caption do Panel1 o valor inteiro correspondente ao booleano “True”/”Verdadeiro”*)
Panel1.Caption := Format(msg,[Cardinal(True)]);

(*exibe a soma do valor inteiro correspondente ao caracter ‘B’, na tabela ASCII,
mais o inteiro correspondente ao booleano “False”. *)

MessageDlg(Format(msg,[Byte(False) + Cardinal('B')]), mtWarning, [mbOK], 0);

(* Atribui ao caption do form o caracter correspondente ao Booleano *)
Self.Caption := Self.Caption +' - ' + Char(vBoolean);

end;


Sinteticamente falando, trata-se de uma forma de “forçar” o compilador a enxergar, considerar, uma variável, um valor, um objeto de um tipo específico como se fosse outro tipo. Entenda “Objeto” como uma instância de uma classe, uma variável que aloca memória dinamicamente para um determinado tipo de classe.

Sintaxe:
No que tange a esse critério, a seguir as formas de sintaxe para fazermos typecast:

A sintaxe para um cast de tipos primitivos é: Tipo(ValorOuVariavel);

Para objetos:

Forma 1 – HardCast (também amplamente referenciado por type cast estilo “C”).

TEdit(Sender).text := ‘Bla bla bla!!! Oba!!!’;
ShowMessage(TEdit(Sender).text);
TEdit(Sender).SetFocus;


Forma 2 - Usando o operador de Typecast “as”

(Sender as TEdit).text := ‘Bla bla bla!!! Oba!!!’;
ShowMessage((Sender as TEdit).text);
(Sender as TEdit).SetFocus;


Usei propositalmente uma variável identificada por “Sender”, visto que, quase todos os eventos dos objetos da VCL possuem um parâmetro que é um ponteiro para o objeto que o chamou (o procedimento) identificado por este nome. Sender é sempre do tipo TObject, portanto, no evento OnClick de qualquer botão, quando ele for executado, o Sender estará apontando para ele.
Contudo, observe o trecho de código acima, Sender é um TObject, ele não possui uma propriedade “Text”. Alias, todas as propriedades que caracterizam um objeto ser um Edit, obrigatoriamente, não são encontradas em TObject. No entanto, para manipular o evento OnMouseMove do Edit, eu tenho como referencia ao objeto que disparou esse evento o parâmetro Sender, cujo o tipo não é TEdit. A través do typecast, eu comunico ao compilador, que embora, no trecho de código, o identificador seja TObject, em tempo de execução um objeto Edit estará alocado naquele endereço de memória.
Não podemos deixar de considerar que o programador pode errar, existem uma infinidade possibilidades na implementação de um programa que torna o typecast exemplificado acima extremamente suscetível a erros. Na verdade, um único e fatal erro. Por exemplo, se por algum motivo no trecho de código acima o identificador Sender não estiver apontando para um Edit. Em última análise, o Sender pode estar apontando para qualquer lugar. Quem nunca viu pérolas como essa nos fontes da vida:

Button1Click(nil);

Nessa situação o Sender esta apontando pra casa do cabula (aonde tem jaca mole). Supondo que a implementação desse evento, “Button1Click”, seja:

// forma 1 - Hardcast
com hardcast
procedure TForm1.Button1Click(Sender: TObject);
begin
TButton(Sender).Left := (Sender as TButton).Left + 20;
TButton(Sender).Caption := 'Andei!!! ... que maravilha!!!';
end;

//forma 2 - Com operador de typecast
procedure TForm1.Button1Click(Sender: TObject);
begin
(Sender as TButton).Left := (Sender as TButton).Left + 20;
(Sender as TButton).Caption := 'Andei!!! ... que maravilha!!!';
end;


O que vc acha que vai acontecer? Se Sender for nulo, não importa qual forma de typecast, vc vai visitar o cabula ... acesso violado de cara. Caso contrário, Sender não é nulo, mas aponta para um tipo incompatível. Veja:


Usando o operador “as”: Na primeira linha, por utilizar o operador “as” ele usa RTTI para verificar se o objeto instanciado na que endereço é de tipo compatível com o que esta proposto pelo programador. Dessa maneira, antes de tentar acessar algo que não exista, ou que seja incompatível, como exemplificado acima, ele executa um teste. Caso não haja compatibilidade é lançada uma exceção de typecast inválido, sem nenhum comprometimento do funcionamento do aplicativo.

Usando o hardcast: por estar sendo feito o “hardcast”, o processador, em run-time, vai acessar o endereço referenciado pelo identificador Sender. Ou seja, a casa do cabula!!! Ele não vai estar em casa, alias, ninguém vai estar em casa. As jacas moles, inevitavelmente, serão acessadas violentamente .... o final da história vc já sabe ... presumo eu, não sei...

Voltando a falar sério, o hardcast não oferece nenhum nível de proteção. Caso haja incompatibilidade de tipos, vc vai levar um "access violation”, que poderá comprometer o funcionamento do aplicativo.

Ora, vc deve estar pensando: Se eu tenho a RTTI para obter dinamicamente informações sobre o tipo do objeto, então eu posso fazer um typecast mais seguro, correto? Mas é claro ... mas é claro. Eu posso usar o outro operador da RTTI, “is”. Com ele antes de fazer o cast eu posso testar se o tipo é compatível com o esperado, desta forma eu consigo um typecast seguro. Consigo eliminar as possibilidades de erro.


procedure TForm1.Button1Click(Sender: TObject);
begin
if (Sender is TButton) then
begin
(Sender as TButton).Left := (Sender as TButton).Left + 20;
(Sender as TButton).Caption := 'Andei!!! ... que maravilha!!!';
end;
end;


Agora, seu cast está seguro, todavia, há que se considerar que, embora não haja erro no código acima, não existe mais vantagem nenhuma em fazer o cast usando o operador “as”. Visto que, o desvio condicional garante que somente tipos compatíveis com TButton sofrerão o cast. Portanto, posso com segurança optar pelo hardcast. Alguns programadores preferem isso, porem, na minha opinião, o ganho que isso pode proporcionar não é representativo. Porque, mesmo que a utilização do operador “as” possa consumir algum recursos do processador, ao consultar a RTTI, frente a performance dos hardwares atuais esse consumo é insignificante.
Vou terminando por aqui .... pode ser que no futuro voltemos a falar sobre esse assunto.
Veja mais exemplos da aplicação de typecast neste artigo.
hum!!! Lembrei de outro.

Artigo completo (View Full Post)

quinta-feira, 3 de maio de 2007

Quer sortear um registro do banco de dados?

Olá a todos.

Neste post algo não muito usual, mas é no mínimo muito legal.

Alguma vez você já precisou fazer uma espécie de 'sorteio' no banco de dados? Tudo bem, eu admito que dificilmente será o caso.

Mas, se você quiser sortear um felizardo dentro do seu banco de dados você não precisa criar um algoritmo que gera um Random(), testa se existe no banco e caso não exista gere Random() de novo <-- sinceramente isso não dá! xD

Vou colocar abaixo como fazer nos diferentes bancos de dados:

MySQL

select [colunas] from [tabela]
order by rand()
limit 1

PostgreSQL:

select [colunas] from [tabela]
order by random()
limit 1


MS SQL Server:

select top 1 [colunas] from [tabela]
order by newid()

IBM DB2

select [colunas] from [tabela]
order by rand()
fetch first 1 rows only

Oracle:

select [colunas] from
( select [colunas] from [tabela]
order by dbms_random.value )
where rownum = 1

Então valeu. Espero que este post ajude em algo. Abraços.

Artigo completo (View Full Post)

Lauryn Hill - The Miseducation Of ... (Partitura)


Pois é... a moça esta na área ...

thanks for your return, thanks because you came here!!!!

Nós, do Estação Zn, durante longos anos sonhamos com esse dia. Obrigado por vc voltar, obrigado por ter vindo até aqui.

Na introdução rola um piano a metro. é um arpejo de Cb7M (um compasso), em seguida um compasso de Abm79 (tb arpejo) onde entra um teclado com som de organ Hammond (irado por sinal!!!), o último acorde da intro é um dominante para Ebm7, os violinos preparam ...


The Miseducation Of Lauryn Hill

Ebm7 Abm7

My world it moves so fast today

The past it seems so far away
Db7 Bbm7 Ebm7
And I squeeze it so tight, I can't breathe
Abm7
And every time I try to be

What someone has thought of me
Db7 Bbm7
So caught up, I wasn't able to achieve
Bbm7 Ebm7 Abm7 Db7 Bbm7
But deep in my heart the answer it was in me
Ebm7 Abm7 Db7
And I made up my mind to find my own destiny
Solo cordas
|Bbm7| Ebm7| Abm7| Db7| Bbm7| Ebm7| Abm7| Db7 Dº|

Ebm7 Abm7
I look at my environment

And wonder where the fire went
Db7 Bbm7 Ebm7
What happened to everything we used to be
Abm7
I hear so many cry for help

Searching outside of themselves
Db7
Now I know that His strength is within me
Bbm7 Ebm7 Abm7 Db7
And deep in my heart the answer it was in me
Bbm7 Ebm7`Abm7 Db7
And I made up my mind to find my own destiny
Bbm7 Ebm7 Abm7 Db7
And deep in my heart the answer it was in me
Bbm7 Ebm7 Abm7 Db7 Dº Gb
And I made up my mind to find my own destiny









Cifra

Artigo completo (View Full Post)

 
BlogBlogs.Com.Br