POO - Bug ou erro de programacao?
ola pessoal
imaginem a seguinte classe
type
TConexao = class
private
FSqlQuery: TIBSQL;
FSQSQL: TStringList;
procedure SetSQSQL(const Value: TStringList);
public
constructor Create;
destructor Destroy; override;
procedure SQExecutar;
published
property QRSQL: TStringList read FQRSQL write SetQRSQL;
property SQSQL: TStringList read FSQSQL write SetSQSQL;
end;
constructor TConexao.Create;
begin
inherited;
FSqlQuery:=TIBSQL.Create(nil);
FSqlQuery.Database:=<ojebto IBDatabase>;
FSqlQuery.Transaction:=<objeto IBTransaction>;
FSQSQL:=TStringList.Create;
end;
destructor TConexao.Destroy;
begin
FreeAndNil(FSqlQuery);
FreeAndNil(FSQSQL);
inherited;
end;
procedure TConexao.SQExecutar;
begin
FSqlQuery.ExecQuery;
end;
procedure TConexao.SetSQSQL(const Value: TStringList);
begin
FSQSQL:=Value;
FSqlQuery.SQL:=FSQSQL;
end;
o problema nessa classe eh que o metodo SetSQSQL nunca eh executado... tanto que se vc colocar um brakpoint dentro do procedimetno SetSQSQL ele ira ficar desabilitado... como se o compiliador tivesse ignorado este procedimento..
eu ja troquei o tipo de dados do campo FSQSQLpara TStrings e no constructor instansiei como sendo TStringList e mesmo assim nao funcionou...
a unica maneira que deu certo foi quando eu troquei o tipo de dados do campo FSQSQL para string... apos ter feita essa alteracao tudo passou a funcionar corretamente...
ja olhei outros objetos do proprio delphi que tenhao propriedade do tipo TStrings ou TStringList pra ver se eles trabalhão de maneira diferente, mas nao encontrei nada que fosse fazer diferenca...
muito estranho esse erro... o mais estranho eh que todos os programadores que conheco nunca viram esse tipo de erro...
aguardo a ajuda do forum.... :cry:
obrigado
imaginem a seguinte classe
type
TConexao = class
private
FSqlQuery: TIBSQL;
FSQSQL: TStringList;
procedure SetSQSQL(const Value: TStringList);
public
constructor Create;
destructor Destroy; override;
procedure SQExecutar;
published
property QRSQL: TStringList read FQRSQL write SetQRSQL;
property SQSQL: TStringList read FSQSQL write SetSQSQL;
end;
constructor TConexao.Create;
begin
inherited;
FSqlQuery:=TIBSQL.Create(nil);
FSqlQuery.Database:=<ojebto IBDatabase>;
FSqlQuery.Transaction:=<objeto IBTransaction>;
FSQSQL:=TStringList.Create;
end;
destructor TConexao.Destroy;
begin
FreeAndNil(FSqlQuery);
FreeAndNil(FSQSQL);
inherited;
end;
procedure TConexao.SQExecutar;
begin
FSqlQuery.ExecQuery;
end;
procedure TConexao.SetSQSQL(const Value: TStringList);
begin
FSQSQL:=Value;
FSqlQuery.SQL:=FSQSQL;
end;
o problema nessa classe eh que o metodo SetSQSQL nunca eh executado... tanto que se vc colocar um brakpoint dentro do procedimetno SetSQSQL ele ira ficar desabilitado... como se o compiliador tivesse ignorado este procedimento..
eu ja troquei o tipo de dados do campo FSQSQLpara TStrings e no constructor instansiei como sendo TStringList e mesmo assim nao funcionou...
a unica maneira que deu certo foi quando eu troquei o tipo de dados do campo FSQSQL para string... apos ter feita essa alteracao tudo passou a funcionar corretamente...
ja olhei outros objetos do proprio delphi que tenhao propriedade do tipo TStrings ou TStringList pra ver se eles trabalhão de maneira diferente, mas nao encontrei nada que fosse fazer diferenca...
muito estranho esse erro... o mais estranho eh que todos os programadores que conheco nunca viram esse tipo de erro...
aguardo a ajuda do forum.... :cry:
obrigado
Diviex
Curtidas 0
Respostas
Massuda
04/09/2006
procedure TConexao.SetSQSQL(const Value: TStringList);
begin
FSQSQL:=Value;
FSqlQuery.SQL:=FSQSQL;
end;
Não sei se isso tem a ver com o que você descreveu, mas normalmente essa procedure seria implementada assim...procedure TConexao.SetSQSQL(const Value: TStringList); begin //FSQSQL.Clear; FSQSQL.AddStrings(Value); //FSqlQuery.SQL.Clear; FSqlQuery.SQL.AddStrings(Value); end;
GOSTEI 0
Diviex
04/09/2006
Não sei se isso tem a ver com o que você descreveu, mas normalmente essa procedure seria implementada assim...Código:
procedure TConexao.SetSQSQL(const Value: TStringList);
begin
//FSQSQL.Clear;
FSQSQL.AddStrings(Value);
//FSqlQuery.SQL.Clear;
FSqlQuery.SQL.AddStrings(Value);
end;
...assim a lista FSQSQL criada no construtor não é perdida ao ser substituída por Value.
mesmo assim ainda nao deu...
o compilador ainda continua ignorando o procedimento, ou seja, mesmo vc alterando a pripriedade SQSQL do objeto TConexao, o campo FSQSQL permanece sem alteracao pq o evento SetSQSQL sequer xega a ser executado
procedimento onde se altera a propriedade SQSQL do objeto TConexao
var
Conexao1: TConexao;
begin
Conexao1:=TConexao.Create;
{demais codigos}
Conexao1.SQSQL.Clear;
Conexão1.SQSQL.Add(´texto a ser adicionado´);
FreeAndNil(Conexao1);
end;
a imagem abaixo mostra o procedimento que seria responsavel por fazer a atualizacao do campo FSQSQL durante a execucao do programa
observe que os brakpoints estao desabilitados, ou seja o compilador nao reconhece as linhas onde estao os brakpoint pq ele nunca passara por la..
mas porque ele faz isso se pela logica ele passara por lah varias vezes???
GOSTEI 0
Massuda
04/09/2006
O compilador só elimina código se perceber que o código nunca é utilizado.
Isso pode ser desabilitado em Project|Options, aba Compiler, desmarcando a opção Optimization.
Entretanto, o fato do código estar desabilitado pode inidicar que você omitiu a chamada a procedure SetSQSQL (ou a atribuição à propriedade SQSQL) ou existe no seu programa uma situação tal que a chamada nunca ocorrerá.
Isso pode ser desabilitado em Project|Options, aba Compiler, desmarcando a opção Optimization.
Entretanto, o fato do código estar desabilitado pode inidicar que você omitiu a chamada a procedure SetSQSQL (ou a atribuição à propriedade SQSQL) ou existe no seu programa uma situação tal que a chamada nunca ocorrerá.
GOSTEI 0
Diviex
04/09/2006
sobre o optimization eu ja tinha desabilitado...
mais entaum cara.... o programa em si esta xamando a proprieade SQSQL sim... mais mesmo assim, na propria unit onde esta declarada a classe TConexao, existe outra classe que esta xamando pelo menos uma vez a propriedade em questão...
e agente nao pode se esquecer de um detalhes importante... trocando o tipo de dados de TStringList para String... o problema eh 100¬ resolvido...
atualmente eu estou trabalhando com o tipo String para o programa nao ficar parado, porem, nao ficou legal... pois ´politicamente´ correto, seria usar o TStrings ou TStringList...
vc tem mais alguma ideia do que pode ser??
eu tenho um programa de demostracao desse erro (pq ele ja eh de longa data e ninquem consequiu uma solucao ate hoje)... caso vc (ou outros que queiram ajudar) queira, pode pega-lo no link [url]http://www.dvx.grandsinformatica.com.br/demo_erro.zip[/url]
obrigado novamente
mais entaum cara.... o programa em si esta xamando a proprieade SQSQL sim... mais mesmo assim, na propria unit onde esta declarada a classe TConexao, existe outra classe que esta xamando pelo menos uma vez a propriedade em questão...
e agente nao pode se esquecer de um detalhes importante... trocando o tipo de dados de TStringList para String... o problema eh 100¬ resolvido...
atualmente eu estou trabalhando com o tipo String para o programa nao ficar parado, porem, nao ficou legal... pois ´politicamente´ correto, seria usar o TStrings ou TStringList...
vc tem mais alguma ideia do que pode ser??
eu tenho um programa de demostracao desse erro (pq ele ja eh de longa data e ninquem consequiu uma solucao ate hoje)... caso vc (ou outros que queiram ajudar) queira, pode pega-lo no link [url]http://www.dvx.grandsinformatica.com.br/demo_erro.zip[/url]
obrigado novamente
GOSTEI 0
Diviex
04/09/2006
alguem pra ajudar???? :?: :cry:
GOSTEI 0
Siam
04/09/2006
Acredito que o problema esteja na property definida; ou seja; o compilador naõ entende como [b:08907d737b]write[/b:08907d737b] quando vc mexe no objeto.
Se vc fizer: SQSQL := nil; aí sim ele irá entender como um [b:08907d737b]write[/b:08907d737b] e executar a procedure.
Se vc fizer: SQSQL := nil; aí sim ele irá entender como um [b:08907d737b]write[/b:08907d737b] e executar a procedure.
GOSTEI 0
Diviex
04/09/2006
Siam....
me escplica melhor essa parte do SQSQL:=nil.
isso seria colocado no constructor da classe, ou em algum outro lugar???
me escplica melhor essa parte do SQSQL:=nil.
isso seria colocado no constructor da classe, ou em algum outro lugar???
GOSTEI 0
Diviex
04/09/2006
Siam....
me explica melhor essa parte do SQSQL:=nil.
isso seria colocado no constructor da classe, ou em algum outro lugar???
me explica melhor essa parte do SQSQL:=nil.
isso seria colocado no constructor da classe, ou em algum outro lugar???
GOSTEI 0
Siam
04/09/2006
O que estava querendo dizer é que acho que o compilador entende como um [b:ec0d7e47a1]write[/b:ec0d7e47a1] quando vc escreve diretamente no ponteiro do objeto e não no conteúdo desse ponteiro.
GOSTEI 0
Night_man
04/09/2006
assim....
quando tu muda os items de um StringList tu nao esta mudando o variavel do tipo StringLista, esta mudando algo dentro dela
Quando voce muda o text do teu SQL nao dipara write, pois o SQL nao foi mudado e sim os items dele
faca o seguinte no evento OnChange do StringList atribu o metodo SetSQSQL, dai toda vez que os items forem mudados ele sera chamado
quando tu muda os items de um StringList tu nao esta mudando o variavel do tipo StringLista, esta mudando algo dentro dela
Quando voce muda o text do teu SQL nao dipara write, pois o SQL nao foi mudado e sim os items dele
faca o seguinte no evento OnChange do StringList atribu o metodo SetSQSQL, dai toda vez que os items forem mudados ele sera chamado
GOSTEI 0