Tem como alterar em RUN - TIME o valor de uma constante???

Delphi

19/07/2005

pessoal gostaria d saber se existe a possibilidade dealterar o valor de uma constante em RUN - TIME, e ela permanecesse com esta alteração...


ou se tem como alterar os dados de array static....


Agradeço antecipadamente desde já...


Cabelo

Cabelo

Curtidas 0

Respostas

Motta

Motta

19/07/2005

Não complique.

Já que vai mudar use uma variável.


GOSTEI 0
Kapak

Kapak

19/07/2005

pessoal gostaria d saber se existe a possibilidade dealterar o valor de uma constante em RUN - TIME, e ela permanecesse com esta alteração...
Const Int7:Integer = 7; var p:PChar; Int8:Integer;
begin
  ShowMessage(IntToStr(Int7));
  p    := @Int7;
  Int8 := 8;
  Move(Int8, p^, 4);
  ShowMessage(IntToStr(Int7));
end;
ou se tem como alterar os dados de array static....
Faça um [b:efc3c46218]for[/b:efc3c46218] variando o ponteiro [b:efc3c46218]p[/b:efc3c46218]


GOSTEI 0
Massuda

Massuda

19/07/2005

Acho que basta fazer...
const
  K: Integer = 7;
...
  K := 8;
...
...desde que a opção [b:975f3cf528]Assignable typed constants[/b:975f3cf528] em [b:975f3cf528]Project|Options|Compiler[/b:975f3cf528] esteja marcada.

Com essa opção marcada, toda constante cujo tipo seja declarado (no exemplo, K é Integer) pode ter seu valor alterado. Independente se essa opção está ou não marcada, este código...
const
  K = 7;
...
  K := 8;
...
...nem compila.


GOSTEI 0
Motta

Motta

19/07/2005

Posso parecer louco mas uso constant para valores que não pretendo mudar, definir uma constante e ficar preocupado em manipular ponteiro , ou opções de compilação para altera-las é complicar à tóa.

As soluções citadas são legais do ponto de vista acadêmico para entender como as coisas funcionam mas na prática não seria melhor simplificar ??!!

Kiss (Keep it simple student) já disse alguém


GOSTEI 0
Rjun

Rjun

19/07/2005

Motta

então somos dois loucos...acho que constante tem esse nome por algum motivo...


GOSTEI 0
Daemon

Daemon

19/07/2005

Apesar das ótimas soluções apresentadas pelos camaradas, não pegue esse costume, constantes é para ter o seu valor invariável, se é para variar, use variáveis (rs. ..soou até meio estranho) ...de qualquer maneira, com ponteiro vc pode fazer isso, assim como apresentado, vc pode até, em ponteiro, trocar o tipo de uma variavel de, por exemplo, float para inteiro EM RUNTIME, mas de maneira nenhuma é aconselhavel ser feito, mesmo pq, esse tipo de implementação pode complicar seu proprio debug, ou de outros, mais para frente. ....faça sempre bom uso dos bons costumes de implementação de sistemas. ....
...flws


GOSTEI 0
Massuda

Massuda

19/07/2005

Concordo que uma constante deveria ter seu valor imutável, mas o fato de ser possível modificar o valor de constantes tipadas (com tipo declarado) existe (se não me engano) desde os tempos do TurboPascal e está habilitado por default no Delphi.

Que eu saiba, isso tem apenas dois usos...[list:1f2be9339a][*:1f2be9339a]compilar código antigo que usava isso para compensar o fato do TP/Delphi não inicializar automaticamente variáveis comum determinado valor escolhido pelo programador (sei que o Delphi hoje faz isso, mas ele não fazia isso nas primeiras versões)[*:1f2be9339a]simular (usando uma terminologia estilo C) uma variável local estática, isto é, algo como uma variável global mas com escopo reduzido (normalmente o escopo dessa variável seria uma function ou procedure)[/list:u:1f2be9339a]


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Colegas...

Adorei colocar em pauta este assunto, pois já ví que é um assunto polêmico..

Agradeço muito a ajuda de todos..

Entre tantos, que optaram por solucionar o problema estão os que opnaram pelo uso de variáveis, sei que é o correto e é assim que eu uso nos meus sistema..

mas acho que vocês não entenderam a minha questão.. a questão é :

Existe alguma forma de manipular estas constantes criadas em desing-time, alterá-las em runtime, e elas permanecerem mudadas, isto é, quero saber se dá pra usar uma UNIT como banco de dados????

Armazenando dados nas constantes, para isso seria necessário mudar o valor atribuido inicialmente a uma constante, ou um static array...

acredito que deve ser assim que um BD funciona, por isso postei esta idéia..


GOSTEI 0
Massuda

Massuda

19/07/2005

...acredito que deve ser assim que um BD funciona, por isso postei esta idéia..
Não entendi... você queria alterar uma constante do programa e espera que [b:d18c844c77]na próxima[/b:d18c844c77] execução do programa o valor alterado continue lá no programa?


GOSTEI 0
Kapak

Kapak

19/07/2005

Modificar o valor de constantes as vezes pode ser útil; como por ex: no caso de um array de fim de meses:
const rFim_Mes:array[1..12] of Byte = (31,00,31,30,31,30,31,31,30,31,30,31);
Neste caso, dependendo do ano muda-se o segundo elemento p/ 28 ou 29.
Ao passo que declarar uma variável, teria-se que alimentar os elementos um a um.


GOSTEI 0
Cabelo

Cabelo

19/07/2005

[quote:cf0ab6eaf1=´Cabelo´]...acredito que deve ser assim que um BD funciona, por isso postei esta idéia..
Não entendi... você queria alterar uma constante do programa e espera que [b:cf0ab6eaf1]na próxima[/b:cf0ab6eaf1] execução do programa o valor alterado continue lá no programa?[/quote:cf0ab6eaf1]

Massuda.. é exatamente isso.. gostaria de saber se é possível..


Modificar o valor de constantes as vezes pode ser útil; como por ex: no caso de um array de fim de meses:
const rFim_Mes:array[1..12] of Byte = (31,00,31,30,31,30,31,31,30,31,30,31);
Neste caso, dependendo do ano muda-se o segundo elemento p/ 28 ou 29. Ao passo que declarar uma variável, teria-se que alimentar os elementos um a um.


Kapak

este é um bom exemplo, você tem idéia de como fazer isso ?


GOSTEI 0
Massuda

Massuda

19/07/2005

[quote:a6cae074f3=´Massuda´][quote:a6cae074f3=´Cabelo´]...acredito que deve ser assim que um BD funciona, por isso postei esta idéia..
Não entendi... você queria alterar uma constante do programa e espera que [b:a6cae074f3]na próxima[/b:a6cae074f3] execução do programa o valor alterado continue lá no programa?[/quote:a6cae074f3]

... é exatamente isso.. gostaria de saber se é possível..[/quote:a6cae074f3]Não tem como fazer isso. Um dos motivos é que não é possível alterar o conteúdo de um arquivo em execução (no caso, seu programa).

Talvez outras idéias surjam se você explicar melhor o que pretende fazer.


GOSTEI 0
Daemon

Daemon

19/07/2005

1. ...não sei se isso resolve sua questão, mas nesse caso ainda não seria o correto alterar essas constantes, o certo seria vc criar um Reg do seu sistema, ou se não precisa de tanto, talvez soh um INI;

2. quanto à questão do ultimo dia do mes, ainda assim não é necessário se fazer a modificação de constante, pois existem outras formas mais praticas de ser fazer isso;

3. o que vc queria, no caso, não seria alterar a sua constante, mas sim reescrever o código no que diz respeito ao valor dessa constante;


GOSTEI 0
Kapak

Kapak

19/07/2005

este é um bom exemplo, você tem idéia de como fazer isso ?
Neste caso é simples; basta vc acessar o endereço de memória do segundo elemento e atribuir o valor:
var p:PChar;
begin
  p := @rFim_Mes[2];
  p^ := 28;
end;
2. quanto à questão do ultimo dia do mes, ainda assim não é necessário se fazer a modificação de constante, pois existem outras formas mais praticas de ser fazer isso;
Mas este foi só um exemplo; assim como este pode surgir outras necessidades de alterar apenas um dos ítens de um array de constantes.


GOSTEI 0
Cabelo

Cabelo

19/07/2005

3. o que vc queria, no caso, não seria alterar a sua constante, mas sim reescrever o código no que diz respeito ao valor dessa constante;


É exatamente esta minha pergunta.. tem como??

[quote:ee934d3e0e=´Cabelo´]este é um bom exemplo, você tem idéia de como fazer isso ?
Neste caso é simples; basta vc acessar o endereço de memória do segundo elemento e atribuir o valor:
var p:PChar;
begin
  p := @rFim_Mes[2];
  p^ := 28;
end;
2. quanto à questão do ultimo dia do mes, ainda assim não é necessário se fazer a modificação de constante, pois existem outras formas mais praticas de ser fazer isso;
Mas este foi só um exemplo; assim como este pode surgir outras necessidades de alterar apenas um dos ítens de um array de constantes.[/quote:ee934d3e0e]

Fiz o teste aqui e funcionou bem, já tinha a tempos trabalhado com ponteiros, e acessos físicos àos endereços de memória..

Mas minha pergunta é...

se eu fizer isso, fechar o programa, e depois abrir, como faço para manter este mesmo valor para a segunda posição?


GOSTEI 0
Beppe

Beppe

19/07/2005

Bom, em suma, existem 3 caminhos para modificar uma constante.

* Constantes tipadas
* Via ponteiro
* Self-modifying code(apenas literais numéricas) - muito difícil de fazer, e nem sempre possível

Mas sua última pergunta não envolvem bem constantes...
se eu fizer isso, fechar o programa, e depois abrir, como faço para manter este mesmo valor para a segunda posição?

O Delphi não possui a capacidade de armazenar variáveis globais de maneira persistente. Use o registro, DB, INI´s para isso.

BD´s tem uma estrutura beeeeem diferente, pois podem armazenar um número n de registros, sem tamanho fixo(digo, tabelas).


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Mas sua última pergunta não envolvem bem constantes... [quote:e98e8a1978=´Cabelo´]se eu fizer isso, fechar o programa, e depois abrir, como faço para manter este mesmo valor para a segunda posição?

O Delphi não possui a capacidade de armazenar variáveis globais de maneira persistente. Use o registro, DB, INI´s para isso.

BD´s tem uma estrutura beeeeem diferente, pois podem armazenar um número n de registros, sem tamanho fixo(digo, tabelas).[/quote:e98e8a1978]

Beppe.. valeu pelas dicas.. era exatamente isso que queria saber..

Minha idéia seria seria criar um sistema com um banco de dados ´interno´ sem arquivos adicionais, mesmo que seja só o banco de dados..

Não conheço uma estrutura de banco de dados, internamente, só conheço o que uso..rss..

desculpe a ignorância, mas achei que fosse uma pergunta que se tivesse uma resposta positiva, poderia mudar meu modo de usar os bd´s..

muito obrigado a todos pelas dicas..


GOSTEI 0
Motta

Motta

19/07/2005

Voce procurar material sobre persistencia de objetos, a sqlmagazine vem publicando artigos sobre isto.


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Por quê colega.. você acha que existe como trabalhar com alterações em persistências?? :D


GOSTEI 0
Motta

Motta

19/07/2005

Por quê colega.. você acha que existe como trabalhar com alterações em persistências?? :D


¡¿?!


GOSTEI 0
Beppe

Beppe

19/07/2005

Meses atrás eu trabalhei em cima de uma camada de persistência, até onde eu fui ficou bem legal...Bastava só criar uma classe com ums métodos adicionais e o resto o framework fazia...mas para esse caso acho bem mais simples usar um INI. Ou o Cabelo tem muito coisa a persistir?


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Meses atrás eu trabalhei em cima de uma camada de persistência, até onde eu fui ficou bem legal...Bastava só criar uma classe com ums métodos adicionais e o resto o framework fazia...mas para esse caso acho bem mais simples usar um INI. Ou o Cabelo tem muito coisa a persistir?


Beppe..

Eu quero usar os .Pas do delphi, criando várias constantes, e alter-a - las em RUN TIME, sendo que elas devam ficar gravadas, inclusive a alteração..

Seria mais ou menos um programa com o banco de dados ´interno´, pois se eu conseguir mudar essas constantes, posso alterar também um static array, aí sim criar um banco de dados interno.


GOSTEI 0
Beppe

Beppe

19/07/2005

Assim não dá no delphi atual...

Se forem strings, tem um jeito mais fácil de contornar:

UmaStringConst = 0;
OutraStringConst = 1;

Essas constantes são um índice em um arquivo texto, que vc salvará ao fechar o programa e carregará dele ao abrir, usando um TStringList(Consts) auxiliar. Pra acessar uma const dessas, faça Consts[UmaStringConst]. Mas isso se forem string né...


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Assim não dá no delphi atual... Se forem strings, tem um jeito mais fácil de contornar: UmaStringConst = 0; OutraStringConst = 1; Essas constantes são um índice em um arquivo texto, que vc salvará ao fechar o programa e carregará dele ao abrir, usando um TStringList(Consts) auxiliar. Pra acessar uma const dessas, faça Consts[UmaStringConst]. Mas isso se forem string né...


Entendí..

Por Quê se for um ampo diferent de string não daria pra fazer, mas e se ao invés disso eu trabalhar com carcteres hexadecimais e armazená - los como string??

Voê acha que daria?


GOSTEI 0
Beppe

Beppe

19/07/2005

O problema é que é muito código pra digitar, que não conpensa fazer. Mas pode armazenar a representação em string de todos os tipos(não precisa ser hexa), e converter na hora de usar, mas é muito trabalho, já que salvar e carregar apenas em dois pontos do sistema e acessar pode ser vários.


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Mas você não concorda que assim eu teria o banco de dados e o executável num mesmo arquivo..??


GOSTEI 0
Massuda

Massuda

19/07/2005

...Mas pode armazenar a representação em string de todos os tipos(não precisa ser hexa), e converter na hora de usar...
Estou com a sensação que estamos a um passo de reinventar o arquivo INI...


GOSTEI 0
Beppe

Beppe

19/07/2005

Sim...mas não seria mais complicado do que a versão que eu já propus no primeiro post(com INIs)?

Mas se preferir assim, vá adiante.


GOSTEI 0
Massuda

Massuda

19/07/2005

...assim eu teria o banco de dados e o executável num mesmo arquivo..??
Pelo que entendi, o Beppe sugeriu você ter um arquivo texto com os dados e se programar ler/atualizar esse arquivo; logo, o ´banco de dados´ está em um arquivo separado.


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Seria sim, mas este arquivo eu tenho como carregá-lo dentro do delphi..

Sugestão do Nildo, sem precisar de instalação nenhuma, seria um .txt com os dados do ´banco´..

Estou iniciando a programação aqui, vou postando os resultados para trabalhar em conjunto..


GOSTEI 0
Kapak

Kapak

19/07/2005

Um banco de dados num txt. Qual seria a vantagem disso ?


GOSTEI 0
Cabelo

Cabelo

19/07/2005

Um banco de dados num txt. Qual seria a vantagem disso ?


Seria que posso armazenar este arquivo em forma de um array static, conforme aplicativo do Nildo, dentro do delphi, isto irá fazer com que o meu programa utilize apenas um arquivo para funcionar, isto é, somento o .exe, sem depender de instalações externas, como o banco de dados Server/Client, BDE, entre outros...


GOSTEI 0
Daemon

Daemon

19/07/2005

...bom cara. ...ao invés de usar TXT para guardar informações, você pode, assim como disse antes, guardar informações em um INI... ..ou ainda, se for muitos dados, você pode usar um ClientDataSet. Isso tem como vantagem, em cima do TXT, a velocidade da pesquisa, e ainda não precisa instalar o software, basta levar o arquivo juntamente com o .exe. ....


GOSTEI 0
Beppe

Beppe

19/07/2005

Não encontrei a sugestão do nildo no tópico, mas seria aquele esquema de incluir o arquivo como recurso? Se for, o ´banco´ será somente-leitura, não se pode modificar arquivos de recurso no próprio .exe.


GOSTEI 0
Cabelo

Cabelo

19/07/2005

...bom cara. ...ao invés de usar TXT para guardar informações, você pode, assim como disse antes, guardar informações em um INI... ..ou ainda, se for muitos dados, você pode usar um ClientDataSet. Isso tem como vantagem, em cima do TXT, a velocidade da pesquisa, e ainda não precisa instalar o software, basta levar o arquivo juntamente com o .exe. ....


ClientDataSet ???????? Virou banco ???

Levar um arquivo junto, mas é exatamente isso que não quero.. e qual arquivo seria esse ??

Não encontrei a sugestão do nildo no tópico, mas seria aquele esquema de incluir o arquivo como recurso? Se for, o ´banco´ será somente-leitura, não se pode modificar arquivos de recurso no próprio .exe.


Seria sim Beppe, mas estou fazendo uma versão RUN - TIME da idéia do Nldo, que é essa mesma, seria um static array somente-leitura, mas se trabalhar com um .PAS paralelo a esse acho que vai dar certo, por iria criar um .PAS temporário para ir armazennado as alterações neste .txt, e depois iria sobrepor o .PAS principal, sempre na hora de fechar..

O que acha??


GOSTEI 0
Massuda

Massuda

19/07/2005

...mas se trabalhar com um .PAS paralelo a esse acho que vai dar certo, por iria criar um .PAS temporário para ir armazennado as alterações neste .txt, e depois iria sobrepor o .PAS principal, sempre na hora de fechar...
Não existe .PAS em tempo de execução... do que você está falando? Quando o programa está executando, existe apenas o arquivo executável dele (.EXE e, se for o caso, DLLs e BPLs). Mesmo que seu cliente tenha um Delphi instalado, não seria possível ao compilador recompilar um programa em execução.


GOSTEI 0
Nildo

Nildo

19/07/2005

Não encontrei a sugestão do nildo no tópico, mas seria aquele esquema de incluir o arquivo como recurso? Se for, o ´banco´ será somente-leitura, não se pode modificar arquivos de recurso no próprio .exe.


Na verdade o arquivo não é incluso como Recurso, mas sim como uma Array estática em um arquivo PAS, para compilar esse array com seu programa.


GOSTEI 0
Kapak

Kapak

19/07/2005

Posso estar enganado, mas a única solução que vejo é vc ser um escovador de bits, ir no executável, saber onde estão gravadas as constantes e alterá-las.


GOSTEI 0
Cabelo

Cabelo

19/07/2005

[quote:da3428c850=´Cabelo´]...mas se trabalhar com um .PAS paralelo a esse acho que vai dar certo, por iria criar um .PAS temporário para ir armazennado as alterações neste .txt, e depois iria sobrepor o .PAS principal, sempre na hora de fechar...
Não existe .PAS em tempo de execução... do que você está falando? Quando o programa está executando, existe apenas o arquivo executável dele (.EXE e, se for o caso, DLLs e BPLs). Mesmo que seu cliente tenha um Delphi instalado, não seria possível ao compilador recompilar um programa em execução.[/quote:da3428c850]

É verdade, não existe mesmo essa possibilidade, já que estamos falando sobre persistências...

[quote:da3428c850=´Beppe´]Não encontrei a sugestão do nildo no tópico, mas seria aquele esquema de incluir o arquivo como recurso? Se for, o ´banco´ será somente-leitura, não se pode modificar arquivos de recurso no próprio .exe.


Na verdade o arquivo não é incluso como Recurso, mas sim como uma Array estática em um arquivo PAS, para compilar esse array com seu programa.[/quote:da3428c850]


E aí Nildo, blz.. eu sei que é um array static em um .PAS, já fiz vários testes aqui, pois achei fantástico essa solução..

Na veradde o quê eu quero fazer parece ser impossível.
Posso estar enganado, mas a única solução que vejo é vc ser um escovador de bits, ir no executável, saber onde estão gravadas as constantes e alterá-las.


Se eu conseguisse fazer isso, talvez eu pudesse criar um array dinâmico, armazenando e criando constantes. Mas acho que não é possível criar esse tipo de solução.


GOSTEI 0
POSTAR