Episódio 13 — Macros, Contexto e Reutilização: a linguagem que pensa com você
No episódio anterior, evoluímos para uma linguagem declarativa que aceita condições básicas, permitindo bifurcações e filtros. Mas o próximo salto é essencial: como reaproveitar blocos de código, criar atalhos e permitir que nossa linguagem tenha memória e contexto?
A resposta está em macros, contexto de execução e reuso. Vamos entender como isso se encaixa na arquitetura baseada em TSafeThreadInterface + TTaskChain, e como esse novo "sabor" da linguagem declarativa se adapta ao Delphi com elegância.
Problema: a repetição mata a manutenção
Imagine um fluxo onde você sempre precisa verificar se o usuário está autenticado antes de executar uma ação. Hoje, você repete esse passo em várias partes:
{ "acao": "VerificarLogin" },
{ "acao": "ExecutarPagamento" },
{ "acao": "VerificarLogin" },
{ "acao": "VisualizarExtrato" }
Isso não escala bem. Seria melhor escrever:
{ "macro": "RequerLogin", "acoes": [
{ "acao": "ExecutarPagamento" },
{ "acao": "VisualizarExtrato" }
]}
A macro RequerLogin adicionaria dinamicamente a ação VerificarLogin antes de cada ação do bloco. Mais limpo, mais legível, mais reutilizável.
Introduzindo macros no nosso interpretador
Macros funcionam como expansores de ações:
- Podem ser definidas estaticamente ou em tempo de execução
- Podem acessar variáveis do contexto atual
- Podem injetar, alterar ou cancelar execuções
E o melhor: são processadas antes da execução das ações reais.
Exemplo em Delphi:
procedure RegisterMacro(const Nome: string; ACallback: TMacroCallback);
begin
FMacros.Add(Nome, ACallback);
end;
// Macro que adiciona login antes das ações
RegisterMacro('RequerLogin',
procedure(Context: TContext; var Acoes: TArray<TAcao>)
begin
var NovaLista := TList<TAcao>.Create;
try
NovaLista.Add(CriarAcao('VerificarLogin'));
for var Acao in Acoes do
NovaLista.Add(Acao);
Acoes := NovaLista.ToArray;
finally
NovaLista.Free;
end;
end);
Executando com contexto
Ao processar cada ação, agora temos um Context, que carrega:
- Variáveis globais e locais
- Estado da thread
- Parâmetros e resultados
Com isso, podemos:
- Criar macros que usam variáveis dinâmicas
- Fazer substituições no estilo
{{NomeDoUsuario}} - Condicionar execução a valores do contexto
Exemplo:
{ "acao": "MostrarMensagem", "mensagem": "Olá, {{NomeDoUsuario}}!" }
O interpretador substituirá automaticamente a variável {{NomeDoUsuario}} pelo valor presente no contexto.
Reaproveitamento é poder
Esse modelo abre espaço para:
- Templates de execução reutilizáveis
- Criação de "funções" com parâmetros no estilo JSON
- Redução de acoplamento e aumento de clareza
E tudo isso ainda pode ser executado com TSafeThread e TTaskChain, mantendo performance, cancelamento, controle de erros e sincronismo com a UI.
No próximo episódio... Vamos mostrar como criar funções JSON com parâmetros, para que você possa definir lógicas como:
{ "chamar": "EnviarAlerta", "parametros": { "texto": "Limite atingido!", "nivel": "crítico" } }
E ainda reusar essa lógica quantas vezes quiser. Chegou a hora de dar poder real para o seu interpretador Delphi.