XojoScript, añade funcionalidad en tiempo de ejecución

Se trata de una de las herramientas más potentes y, probablemente, también poco utilizadas. Lo cierto es que XojoScript nos brinda la capacidad de añadir nueva funcionalidad a nuestros productos Desktop, Web y Consola en tiempo de ejecución, lo cual resulta tremendamente atractivo. Además, a la hora de ejecutarse, el código fuente de los scripts será compilado a código máquina, lo que proporciona un extra de seguridad y rendimiento frente a otros lenguajes de script que son interpretados.

Eso sí, no hemos de perder de vista el hecho de que Xojo es un lenguaje de programción de tipado fuerte, lo que se traduce en que el compilador ha de tener toda la información por adelantado sobre los nuevos tipos creados por nosotros (Clases). Y una de las principales limitaciones es que el nuevo código añadido mediante XojoScript no podrá utilizar ninguna de las clases proporcionadas originalmente por el framework de Xojo.

Lo que sí podemos utilizar en nuestro código XojoScript son todos los tipos de datos primitivos y estándar, tales como Double, Integer, Text o Auto, entre otros; así como los Array, todos los operadores tanto alfanuméricos como lógicos, así como los específicos de clase (IsA, Me, Self, etc.) Adicionalmente, la verdadera potencia se encuentra en el hecho de que también podremos definir nuevas clases y también herencia de clases, incluyendo en ellas no sólo la definición de métodos y propiedades (incluidas las propiedades calculadas), sino también la definición de eventos junto con el código asociado; e igualmente podremos definir tanto Interfaces de Clase como Módulos.

Ahora bien, a diferencia de lo que ocurre cuando definimos los módulos en nuestros proyectos, en el caso de XojoScript no podremos definir constantes y las propiedades tendrán un ámbito protegido. No obstante, siempre podremos definir propiedades de ámbito público (globales) como parte de nuestro código XojoScript, así como constantes mediante el uso del comando Const, fuera de la definición de módulo, claro.

Además, en el código de nuestros scripts también tenemos acceso a todos los comandos proporcionados por el framework, excluyendo Declare y GetTypeInfo, de modo que podremos realizar una buena cantidad de operaciones de entrada y salida, en el trabajo con cadenas o bien mostrar alertas y diálogos de interacción con el usuario, entre otras acciones.

Por último, también contaremos para la elaboración de nuestros scripts con el acceso a un nutrido conjunto de las funciones disponibles en el framework clásico de Xojo; facilitando así el trabajo con operaciones de tipo matemático (seno, coseno, máximo, mínimo, potencia, raíz cuadrada, etc.), cadenas y texto (formato, comparación, conversión de mayúscula/minúscula, búsqueda y sustitución, etc.), de tipo numérico, color y también para hallar el número de elementos de un array. Puedes consultar todas las funciones disponibles en esta página del área de desarrolladores de Xojo.

¿Cómo ejecutar los scripts?

Por supuesto, necesitaremos una vía para informar a nuestra aplicación de que queremos ejecutar un nuevo script, y esto es lo que podemos hacer utilizando la clase XojoScript. Como en el caso de otros elementos, puedes hacerlo arrastrando el icono de XojoScript desde la Libreria a una Ventana, ContainerControl o página web, o bien creando una instancia directamente desde código.

Con independencia de cuál sea la vía elegida para obtener la instancia, la forma de indicar el código fuente que deseamos ejecutar es a través de la propiedad Source (lógico, ¿verdad?). Luego, simplemente tendremos que invocar el método Run para ejecutar el código fuente asignado.

Una curiosidad es que si bien en Xojo estamos acostumbrados a utilizar MsgBox para mostrar información al usuario a través de un cuadro de diálogo básico (o ventana de información), cuando se trata de XojoScript utilizamos la palabra clave Print para emitir el texto entrecomillado al evento Print de la instancia. Así, un código como el siguiente en nuestro script:

"Print ""hola Mundo"""

Emitirá la cadena de texto Hola Mundo al evento Print de la instancia. Si deseamos que se muestre un mensaje al usuario, entonces tendremos que implementar el evento Print, para aquellos casos en los que se trate de una instancia que hayamos arrastrado desde la Librería; o bien crear una subclase de XojoScript donde implementemos el evento Print; de modo que posteriormente tendremos que emplear dicha subclase posteriormente cuando creemos instancias desde código.

Dado que el evento Print recibe como parámetro una cadena de texto, el único código que tendremos que incluir en dicho evento para mostrarlo en pantalla será:

Sub Print (msg As String)

   MsgBox msg

End Sub

Advierte también el uso de dobles comillas, puesto que no hemos de perder de vista que el código proporcionado a la propiedad Source de nuestra instancia de la clase XojoScript no deja de ser una cadena de texto.

Recibir entrada del usuario

De igual modo que podemos mostrar información al usuario desde nuestros Scripts, también podemos obtener la entrada de información empleando para ello la función Input, en la que hemos de proporcionar como parámetro la cadena de texto a mostrar como mensaje. La respuesta que obtendremos como resultado de la llamada será también una cadena de texto que asignaremos a una variable del mismo tipo.

Ahora bien, para que esto funcione realmente somos los responsables de proporcionar la interfaz gráfica con el usuario propiamente dicha; algo que haremos implementando el manejador de Evento Input. Dicho manejador recibe como parámetro la cadena de texto, pasada como argumento mediante la función del mismo nombre, y devolverá también la cadena de texto que espera recibir como resultado la función.

Así, dentro del evento podremos crear por ejemplo una instancia de una ventana que presentaremos como modal, y que será la responsable de proporcionar los controles para que el usuario pueda introducir el texto y, una vez cerrada, podremos obtener dicha entrada del usuario almacenada previamente en una propiedad para devolverla finalmente desde el evento.

Otra opción sería la de obtener el valor directamente desde cualquiera de los controles de interfaz de usuario disponibles en la ventana a la que tenga acceso la propia instancia de XojoScript. Por ejemplo, pongamos por caso que la ventana Window1 tiene un control TextField1, y además una instancia de XojoScript en la que hemos implementado el evento Input; por tanto, el siguiente código del evento Input devolvería el valor que tenga asignado el TextField:

Function Input( msg As String ) As String

  Return TextField1.Text

End Function

Gestión de errores

Por supuesto, la clase XojoScript también proporciona una serie de eventos que podemos implementar como respuesta frente a los diferentes tipos de errores posibles:

  • CompilerError. Este es el evento que se dispara en el caso de que se haya producido un error durante la compilación del código fuente pasado mediante la propiedad Source de la instancia. Obtendremos información sobre el tipo de error, de modo que podamos gestionarlo y actuar en consecuencia.
  • RuntimeError. Este es el evento que se dispara cuando se produce un error durante la ejecución del script. Al igual que con el anterior, recibiremos información adicional sobre el tipo de error, de modo que podamos tomar las acciones necesarias.

Acceder a funcionalidad de la aplicación

Como se ha comentado al inicio, en XojoScript no podemos utilizar las clases del framework; es decir, que no podemos crear nuevas instancias de estas. Además, los guiones de XojoScript se ejecutan dentro de su propia SandBox o entorno aislado con respecto a la aplicación sobre la que se está ejecutando (si a esto exceptuamos el acceso a elementos de interfaz de usuario, tal y como hemos visto en el caso del manejador de evento Input). Sin embargo, existe un modo mediante el cual nuestros scripts pueden comunicarse y acceder a los elementos presentes en la aplicación. Esto es lo que logramos asignando un objeto, como pueda ser una ventana o instancia de clase, asignada a la propiedad Context en nuestra instancia XojoScript.

Una vez que lo hagamos, las propiedades y métodos del objeto asignado pasarán a ser globales; eso sí, con la limitación de que no podremos pasar objetos entre el guión y el contexto (por ejemplo a través de los métodos invocados), además de que las Constantes que estuviesen definidas en el objeto de contexto no estarán disponibles para el guión. Por tanto, los métodos o propiedades del Contexto que utilicen objetos no estarán disponibles para el guión.

Por ejemplo, supongamos que contamos con un proyecto que incluye el TextField1 y la instancia de XojoScript (XojoScript1) en la ventana Window1 sobre la que incluimos también una propiedad CadenaTexto de tipo String y ámbito privado, y un PushButton con el siguiente código asociado:

cadenaTexto = TextField1.Text

XojoScript1.Context = Self

XojoScript1.Source = "Print cadenatexto"

XojoScript1.Run

Como puedes observar, como parte del código fuente asignado al script se hace referencia a la propiedad CadenaTexto que en realidad forma parte del objeto Window1. Ahora bien, dado que asignamos el objeto Window1 como Contexto del guión, dicha propiedad pasa a ser global para nuestro guión y por tanto podemos acceder a su contenido.

Conclusión

Como puedes observar, los guiones de XojoScript abren todo un mundo de posibilidades a la hora de ampliar las capacidades de nuestros proyectos, permitiendo por ejemplo ampliar o modificar la funcionalidad de nuestros productos en tiempo de ejecución, ¡y siempre con código compilado!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *