Ícone do site Embarcadero RAD Studio, Delphi, & C++Builder Blogs

Usando o Expressions Engine do Delphi

bindingexpressions

Delphi RTL inclui um motor de expressão muito poderoso, que é uma das bases da arquitetura Live Bindings, mas pode ser usado como um motor separado para o processamento de expressões. Esta postagem do blog oferece uma introdução rápida ao tópico.


Existem muitas joias escondidas no Delphi RTL. Um deles é o motor de expressão. Recentemente, tive algumas conversas com um desenvolvedor Delphi de longa data que estava procurando por um recurso semelhante, sem perceber que já estava no produto há muitos anos. Eu sabia que tinha escrito algumas demos e documentação, então gastei um pouco de tempo procurando por elas e encontrei algumas. Agora, este tópico é muito complexo e não serei capaz de abordá-lo por completo, mas para cenários simples, você realmente precisa de muito pouco código para analisar e processar uma expressão.

Antes de começar com o tópico real, também gostaria de mencionar que recentemente destacamos esse recurso no novo componente VCL NumberBox (adicionado no Delphi 10.4.2, consulte por exemplo  https://blog.marcocantu.com/blog/2021-february -new-vcl-controls-1042.html ). Este componente permite aos usuários finais inserir uma expressão e substituí-la pelo valor resultante. Sem surpresa, ele usou o mecanismo de expressão existente e o faz invocando um método de classe simplificado de

[crayon-67405b12c1a30039723526/]
Neste trecho de código,  LText  é uma string com a expressão e  Value  é o resultado do ponto flutuante. O método de classe TBindings.CreateExpression é um atalho que pode simplificar o código, mas prefiro guiá-lo para mais alguns detalhes.

Principais conceitos de expressões de ligação

O código acima cria um objeto TBindingExpression, a classe principal deste mecanismo. Como o nome indica, ele vai além de ser um avaliador de expressão pura, mas pode “vincular” ou associar a expressão a objetos externos, usando RTTI para integração.

Outro conceito chave das expressões de ligação é que elas não avaliam a entrada de uma maneira completamente dinâmica, mas requerem uma operação de análise (chamada Compilar) que processa o texto e uma operação de avaliação que faz o processamento final. Obviamente, se você não alterar o texto da expressão, poderá compilar uma vez e avaliar a expressão várias vezes com valores diferentes para os objetos associados.

Vamos fazer uma demonstração

Para minha primeira demonstração, criei um formulário com dois controles Memo, um para digitar a expressão e o segundo para exibir a saída. O objetivo aqui é processar strings, não valores numéricos. O código para o único botão usa os objetos de expressão de ligação diretamente, da seguinte maneira:
[crayon-67405b12c1a3a951002517/]
Não que seja muito útil, já que a única operação predefinida para strings é a concatenação, então você pode digitar a entrada:
[crayon-67405b12c1a3d477025263/]
e obter  Hello world como resultado. Observe as aspas duplas na entrada!

Vinculando um objeto

As coisas começam a ficar interessantes quando você associa a expressão a um objeto. Para isso, criei uma classe simples como a seguinte (omiti aqui os campos e métodos privados):
[crayon-67405b12c1a3f832560731/]
Agora posso alterar o código para adicionar um vínculo à expressão, adicionando ao método Compile a associação de um objeto com um nome simbólico (você pode considerá-lo como o nome do objeto para o mecanismo de expressão):
[crayon-67405b12c1a40209228033/]
Com essa extensão, agora posso usar esse objeto em uma expressão como. Por exemplo, depois de atribuir ‘John’ ao nome do objeto pessoa no código, a expressão:
[crayon-67405b12c1a41591194883/]
resultaria em  John está feliz . Mas também posso usar a expressão:
[crayon-67405b12c1a43051532779/]
que fará a transformação do tipo de inteiro em string.

Funções de ligação

As expressões de ligação são limitadas a objetos, mas além de acessar as propriedades, elas também podem executar métodos. Portanto, você pode criar uma classe com vários métodos para serem usados ​​em uma expressão:
[crayon-67405b12c1a44626739326/]
Para invocar esses métodos, você precisa vincular um objeto deste tipo:
[crayon-67405b12c1a45414190380/]
Agora você pode escrever expressões como:
[crayon-67405b12c1a47953573361/]
resultando em:  Com a idade dupla, John terá 66 anos

A IU de demonstração

Não muito sofisticado, mas esta é a demonstração em ação:

Apenas tocando a superfície

Esta introdução está apenas tocando a superfície, já que a expressão de ligação permite controles de ligação e também permite o registro de notificações (uma espécie de mecanismo de retorno de chamada). Eu encontrei mais algumas demos que tentarei postar no blog sobre elas em breve.

Sair da versão mobile