Ícono del sitio Embarcadero RAD Studio, Delphi, & C++Builder Blogs

Usando el motor de expresiones de Delphi

bindingexpressions

Delphi RTL incluye un motor de expresión muy potente, que es uno de los fundamentos de la arquitectura Live Bindings, pero se puede utilizar como un motor independiente para procesar expresiones. Esta publicación de blog ofrece una introducción rápida al tema.


Hay muchas gemas ocultas en Delphi RTL. Uno de ellos es el motor de expresión. Recientemente tuve algunas conversaciones con un desarrollador de Delphi desde hace mucho tiempo que estaba buscando una característica similar, sin darse cuenta de que había estado en el producto durante muchos años. Sabía que había escrito algunas demostraciones y documentación, así que pasé un poco de tiempo buscándolas y encontré algunas. Ahora bien, este tema es muy complejo y no podré cubrirlo en su totalidad, pero para escenarios simples realmente necesita muy poco código para analizar y procesar una expresión.

Antes de comenzar con el tema real, también quería mencionar que recientemente hemos presentado esta función en el nuevo componente VCL NumberBox (agregado en Delphi 10.4.2, consulte, por ejemplo,  https://blog.marcocantu.com/blog/2021-february -nuevo-vcl-controles-1042.html ). Este componente permite a los usuarios finales ingresar una expresión y reemplazarla con el valor resultante. No es de extrañar que haya utilizado el motor de expresión existente y lo hace invocando un método de clase simplificado de

[crayon-676e8d8149609327871222/]
En este fragmento de código,  LText  es una cadena con la expresión y  Value  es el resultado de punto flotante. El método de la clase TBindings.CreateExpression es un atajo que puede simplificar el código, pero prefiero guiarte a más detalles.

Conceptos clave de las expresiones de enlace

El código anterior crea un objeto TBindingExpression, la clase principal de este motor. Como su nombre lo indica, esto va más allá de ser un evaluador de expresiones puro, pero puede “vincular” o asociar la expresión a objetos externos, utilizando RTTI para la integración.

Otro concepto clave de las expresiones vinculantes es que no evalúan la entrada de una manera completamente dinámica, sino que requieren una operación de análisis (llamada Compilar) que procesa el texto y una operación de evaluación que realiza el procesamiento final. Por supuesto, si no cambia el texto de la expresión, puede compilar una vez y evaluar la expresión varias veces con diferentes valores para los objetos asociados.

Vayamos a una demostración

Para mi primera demostración, he creado un formulario con dos controles Memo, uno para escribir la expresión y el segundo para mostrar el resultado. El objetivo aquí es procesar cadenas, no valores numéricos. El código del único botón utiliza directamente los objetos de expresión de enlace, como se muestra a continuación:
[crayon-676e8d8149612433005276/]
No es que sea muy útil, ya que las únicas operaciones predefinidas para cadenas es la concatenación, por lo que puede escribir la entrada:
[crayon-676e8d8149614553335153/]
y obtenga  Hello world como resultado. ¡Observe las comillas dobles en la entrada!

Vincular un objeto

Donde las cosas comienzan a ponerse interesantes es si vincula la expresión a un objeto. Para esto, he creado una clase simple como la siguiente (aquí he omitido los campos y métodos privados):
[crayon-676e8d8149616403849554/]
Ahora puedo cambiar el código para agregar un enlace a la expresión, agregando al método Compile la asociación de un objeto con un nombre simbólico (puede considerarlo como el nombre del objeto para el motor de expresión):
[crayon-676e8d8149617751418645/]
Con esta extensión, ahora puedo usar este objeto en una expresión como. Por ejemplo, después de asignar ‘John’ al nombre del objeto pers en el código, la expresión:
[crayon-676e8d8149619845434454/]
resultaría en que  John esté feliz . Pero también puedo usar la expresión:
[crayon-676e8d814961a481372608/]
que va a hacer la transformación de tipo de Integer a string.

Funciones vinculantes

Las expresiones de enlace se limitan a los objetos, pero además de acceder a las propiedades, también pueden ejecutar métodos. Por lo tanto, puede crear una clase con varios métodos para usar en una expresión:
[crayon-676e8d814961b235406304/]
Para invocar estos métodos, debe vincular un objeto de este tipo:
[crayon-676e8d814961d183505110/]
Ahora puedes escribir expresiones como:
[crayon-676e8d814961e438167849/]
resultando en:  Al doble de edad, John tendrá 66 años

La interfaz de usuario de demostración

No es tan elegante, pero esta es la demostración en acción:

Solo tocando la superficie

Esta introducción solo toca la superficie, ya que la expresión vinculante permite controles vinculantes y también permite registrarse para notificaciones (una especie de mecanismo de devolución de llamada). Encontré algunas demostraciones más que intentaré publicar en un blog sobre ellas pronto.

Salir de la versión móvil