...Ou Como avaliar e executar uma expressão entrada pelo usuário.
O cenário: na aplicação, o usuário pode cadastrar algumas fórmulas, fórmulas que podem conter algumas variáveis previamente cadastradas. Essas variáveis podem conter valores simples, ou ainda, podem ser dependentes de um parâmetro. Um exemplo de fórmula encontrada é a seguinte:(0.50 * ([VAR1(I)] / [VAR1(0)])) + (0.50 * [VAR2])
onde:
- VAR1(I) é uma variável, cujo valor depende do parâmetro "I".
- VAR1(0) é uma variável, cujo valor depende do parâmetro "0".
- VAR2 é a variável simples.
Notem que por convenção, na fórmula, as variáveis estão entre colchetes []. Muitas variáveis são na verdade, séries históricas com valores. Os parâmetros para elas refletem apenas qual a época/data que o valor deve ser considerado.
O problema: dado um intervalo de tempo, preciso saber do valor da fórmula. Ou seja, preciso executar a fórmula, como se fosse parte do programa, ou então fazer o parsing, etc. Em algumas outras linguagens de script, existe a função eval(), que converte um texto (ou seja, uma string) em código, executando-o. Em Caché Object Script, temos o comando XECUTE, que executa o conteúdo de uma String como se fosse código, ou seja, efetua macro substituição.
Mesmo com essa facilidade, ainda assim precisava identificar dentro da %String cada variável. Para isso, escrevi uma pequena função, que coloquei num arquivo .MAC, para ser usada.
Para essa função, passamos a fórmula, bem como caracteres que delimitarão o que será considerado variável, tb passamos uma String que será colocada no lugar da variável na fórmula original, bem como um caracter delimitador (coisa muito usada em sistemas MUMPS-like).
O resultado da função é a fórmula, com as variáveis substituídas pela String, além de todas as variáveis encontradas, separadas na String pelo caracter delimitador. Usando como String de substituição "?", e como caracter delimitador "~", a função para fórmula do exemplo acima retorna:
(0.50 * (? / ?)) + (0.50 * ?)~VAR1(I)~VAR1(0)~VAR2
Em seguida, resolvemos o valor de cada variável, e substituimos na fórmula, e retiramos da String as variáveis. Não vou ilustrar esses passos aqui, pois são bem específicos para o modelo de dados. Neste momento, nossa String da fórmula tem algo como:
(0.50 * (12.3 / 10.88)) + (0.50 * 10)
Note que a sentença é matematicamente bem formada, e inclusive a precedência de operadores é bem explícita com o uso de parênteses, o que deve ser sempre feito, visto que o Caché não segue o padrão matemático quanto a precedência de operadores.
Bem, finalmente vamos executar a expressão. Primeiro, atribuimos o comando SET dentro de uma String, como por exemplo:
SET umaVariavel = "SET resultado = " _ stringComFormula
Depois fazemos o XECUTE:
XECUTE umaVariavel
E pronto! O valor da expressão está na variável "resultado"! Apenas tenham precaução ao usar o comando XECUTE, pois dependendo da situação (e do abuso), ele pode deixar o seu código muito ruim para manutenção.
Nenhum comentário:
Postar um comentário