|
|
|||||||||
| El Amiga Me Encanta ha conseguido el permiso por escrito de IDG Comunications España para ofrecer los artículos de la revista Amiga World España. |
|
![]() |
| CURSO DE AREXX | ||||
|
Un saludo a todos, un mes mas. En este nuevo capítulo, y como lo prometido es deuda, pretendo analizar paso a paso cada línea del programa de ejemplo con el que finalizó el primer capítulo. Se trataba de un programa muy simple, pero me servirá para ilustrar todos los aspectos generales de la programación en ARexx antes de pasar a describir la lista de comandos y funciones del lenguaje. Por ello no deben preocuparse si la descripción de alguna de las instrucciones usadas en el ejemplo está muy simplificada, ya que volverán a verse exhaustivamente en un glosario por orden alfabético durante próximos capítulos. Antes de entrar en materia me gustaría alentarles a que experimentaran modificando a su gusto diferentes aspectos del ejemplo y probando que efecto (o mensaje de error) producen, a medida que analizamos el significado y el por qué de cada línea. No hay mejor método de familiarizarse con un lenguaje de programación que ese. Yo intentaré sugerir algunos posibles cambios didácticos al final, pero les ruego que por favor no se limiten a ellos. Sigan su propia línea de pensamiento y no teman ensayar cualquier cosa que se les ocurra, ya que es virtualmente imposible dañar al ordenador con ello. Naturalmente es muy probable que algunas modificaciones simplemente provoquen mensajes de error del ARexx, pero no deben preocuparse; hasta de ellos puede extraerse información muy útil, y sobre todo el desafío de descubrir qué fue lo que falló cuando acometamos futuros capítulos. Para modificar el programa, recuerden que solo deben arrancar el editor con la orden: "ED rexx:cubo.rexx". Tras hacer los cambios, deben guardarlos con la opción save del menú y salir del editor. En una ventana de Shell podremos ver los resultados con la orden: "rx cubo.rexx". Y ya, sin más dilaciones vamos a empezar a analizar el significado de cada uno de los elementos de nuestro primer programa en ARexx. En primer lugar tomemos las dos primeras líneas que son:
Estas dos líneas son texto de comentario del programa. En ARexx cualquier texto que se encuentre comprendido entre los símbolos "/*" y "*/", es ignorado por el intérprete del lenguaje y nos sirve para añadir notas y comentarios que nos ayuden a aclarar la legibilidad del programa. Un dato muy importante, es que TODOS los programas de ARexx DEBEN comenzar con al menos una línea de comentario. Esta norma sirve para que el intérprete reconozca el texto como un programa en ARexx, y si se intenta ejecutar un programa que no comience así, recibiremos un mensaje de error. Este es un descuido muy típico. La siguiente línea es:
Esta se corresponde con una típica asignación de variable. En este caso, asignamos la cadena de texto "S" a la variable "continuar". En Basic esta línea equivaldría a la expresión: continuar$="S". Para aquellos que no sepan Basic habría que explicar que las variables son pequeñas zonas de memoria donde se guardan temporalmente datos con los que más tarde se va a operar. Las variables pueden contener números o texto indistintamente. Para referirse a esas posiciones de memoria se le da un nombre a cada una. De esta forma, con esta línea reservamos una posición de memoria, a la que llamo arbitrariamente con el nombre "continuar", y guardo en ella la letra "S". El motivo para hacer esto se comprenderá unpoco más adelante. De momento pasemos a la siguiente línea:
Esta instrucción es lo que se llama en programación un "bucle" condicional. Sirve para ejecutar un grupo de instrucciones indefinidamente mientras se cumpla una determinada condición. Cuando esa condición deja de cumplirse, el programa seguirá ejecutándose fuera de ese bucle. El ARexx tiene, como otros lenguajes, varias instrucciones alternativas para hacer bucles. De todas, el "Do While" es la más común, y seguramente conocida por los lectores con conocimientos de Basic, C o Pascal. El grupo de instrucciones que va a ser repetido es el comprendido entre la línea del "Do While" y el "end" de 8 líneas más abajo. En este caso concreto, la condición del bucle es. continuar~="N". Esta expresión significa que se ejecutará el bucle MIENTRAS se cumpla la condición de que la variable "continuar" sea DIFERENTE a la letra "N" (El signo "~=" significa "diferente"). A partir de esto, podemos deducir que ya que precisamentehemos asignado la variable "continuar" con la letra "S", la condición se va a cumplir. Por ello el bucle se va a ejecutar indefinidamente, mientras algo o alguien no cambie el valor de "continuar". Esa es precisamente la función de la variable, actuar como control del bucle. Cuando "continuar" sea igual a "N", la condición dejará de cumplirse, y el bucle saltará a la siguiente instrucción después del "end". Entremos ahora en las instrucciones que componen el cuerpo del bucle:
Esta línea es una de las más sencillas. La instrucción "say" sirve para producir mensajes en la pantalla. En este caso escribirá en la pantalla la frase: "Introduzca numero:". Como veremos un poco más adelante "say" puede ser muy versátil. Si habláramos de Basic, sería equivalente a la instrucción: PRINT "Introduzca numero:". Este texto una vez que ha salido en la pantalla, sirve para avisar al teórico usuario del programa, de la acción de la siguiente instrucción:
La orden "pull" sirve para que el programa solicite un dato al usuario. Siguiendo con la analogía del BASIC, es similar al INPUT. El programa cuando llega a el se detiene a la espera de un dato del teclado. El usuario, como ya habrá visto el mensaje anterior de "Introduzca numero:", tecleará la cifra deseada y pulsará la tecla return. En ese momento el programa se activa de nuevo y guarda lo tecleado en la variable que hemos llamado "numero" en este caso. El significado de la variable "numero" es similar al explicado en el caso de la variable "continuar". Es nuevamente una etiqueta convencional con la que reservamos una zona de memoria donde guarda un dato. La única diferencia con la situación anterior es que la variable "continuar" la inicializamos con la letra "S" dentro del programa, mientras que la variable "numero" se llena con lo que la instrucción "pull" recoja desde el teclado. La siguiente instrucción en el programa implica a una nueva variable:
Aquí definimos una tercera variable que llamamos "resultado, y l allenamos con lo que nos devuelva una peculiar operación que se ejecuta a la derecha del signo igual. En esta línea hacemos una llamada a una "función" definida por nosotros que hemos denominado "cubo". Las funciones son pequeños fragmentos de código que nos permiten dividir el programa e varias tareas más pequeñas. Además nos permiten definir una biblioteca propia de funciones útiles para reutilizarlas en futuros programas, facilitando enormemente el desarrollo de nuevas aplicaciones al no tener que comenzar desde cero. Por otra parte las funciones ya probadas, nos sirven para ocultar los detalles del programa dentro de ellas, facilitando la tarea de depuración de errores en los nuevos programas. El ARexx facilita una biblioteca extensísima de funciones ya definidas que todos podemos usar en los programas, y queveremos próximamente.
Las funciones, para trabajar, aceptan unos valores sobre los que operan, que se llaman "argumentos". Los argumentos se especifican entre paréntesis, después de la llamada a la función. Si se especifica más de un argumento, se colocan separados por comas dentro de los paréntesis. Los argumentos pueden ser valores literales, o variables. A su vez, las funciones pueden devolver o no, resultados. En el caso de nuestro ejemplo, la función "cubo", es llamada con la expresión: "resultado=cubo(numero)". Esto quiere decir que llamamos a "cubo", con la variable "numero" como único argumento, y el resultado que nos devuelva lo guardamos en la variable "resultado". Cuando el ARexx encuentre una expresión del tipo "nombre(argumento)" entiende que se trata de una función, y busca si aparece su definición en su librería interna o en el resto del listado. Si la encuentra, produce un salto en el programa hacía ella, ejecutanto su código, y volviendo después a la línea siguiente a la que llamó. Por el momento no voy a entrar en la sintaxis de la definición de la función "cubo", que aparece unas cuantas líneas más abajo. Aquí nos bastará con ver la función como una verdadera "caja negra", a la que proporcionamos datos y nos devuelve resultados. Al terminar la ejecución de esta línea, lo que nos importa ahora es que dentro de la variable "resultado" vamos a tener el valor que nos entrega la función, que es el cubo de "numero". Con ello el programa pasará a la siguiente línea:
En esta línea nos volvemos a encontrar con "say" una instrucción ya conocida. Como ya indiqué "say" sirve para que el programa pueda ofrecer información en la pantalla. Anteriormente la usamos para imprimir en pantalla una cadena de texto. Ahora vamos a imprimir una cadena de texto compuesta por partes constantes y partes variables. Así las cadenas constantes van entre comillas, como "El cubo de", "es" y ".". Entre ellas están los nombres de dos variables. Cuando say encuentra una cadena entre comillas la imprime literalmente, y cuando encuentra un nombre de variable, imprime el valor que contiene. Por ello, si lavariable "numero" contiene el "numero "5", la variable "resultado" contendrá "125", y por lo tanto en la pantalla veremos:
Es importante darse cuenta de las diferencias entre las cadenas literales entre comillas y los nombres e las variables. En las siguientes líneas, se vuelve a usar say, pero solo con cadenas literales:
Con ello preguntamos al usuario si desea continuar calculando cubos de números, y que teclee "S" si desea continuar o "N" si no desea introducir más números. Después de otra instrucción "say" imprime una cadena con un solo espacio, que sirve para sacar una línea en blanco en la pantalla. Para recoger lo que nuevamente introduzca el usuario tenemos la siguiente línea:
Aquí lo tecleado, se guarda en la variable "continuar". Esta línea es la última del bucle, de forma que una vez ejecutada, el programa pasa a la siguiente línea, donde se encuentra con la instrucción "end" que marca el final efectivo de "Do While", esto hace que el programa salte de nuevo a la primera línea del bucle:
Dónde se volverá a evaluar la condición del bucle en función de lo que el usuario haya respondido a la última pregunta. Si la variable "continuar" todavía contiene la letra "S", la condición se vuelve a cumplir (continuar es diferente de "N"), y con ello se vuelve a dar otra vuelta en las instrucciones que componen el bucle. Si por el contrario "continuar" es "N", la condición es falsa ("continuar es igual a "N"), el bucle termina definitivamente, y la ejecución continua con la siguiente línea después del "end":
En este caso, la instrucción siguiente al bucle es la que indica el final del programa. Todos los programas deben terminar con una instrucción "exit" en algún punto del listado. Cuando el ARexx llega a ella el programa devuelve el control al shell que lo ha activado, ignorando todo el listado que aparezca después del exit. En este caso, después del "exit" nosotros tenemos la definición de la función "cubo" que ya se ejecutó desde la llamada de una línea anterior, así que puede ser ignorado ahora por el ARexx. Analicemos ahora la estructura de la función "cubo". La primera línea que nos encontramos después de exit es una línea de comentario opcional, como las del comienzo:
Al estar enmarcado entre "/*" y "*/" es ignorado. Tras ella comienza la verdadera definición. La siguiente línea es una etiqueta con el nombre de la función:
La etiqueta debe terminar con dos puntos. De esta forma, cuando el listado aparece la típica llamada de una función del tipo "nombre(argumentos)", el ARexx, como ya he contado, busca su definición en sus librerías o buscando la etiqueta "nombre:" en el listado. En la línea siguiente, indicamos al ARexx el número de argumentos que debe recoger desde la llamada:
Cuando llamamos a "cubo" lo hacemos con un solo argumento, es decir la variable numero. Con la instrucción "arg" le decimos al ARexx que recoja el argumento (el contenido de la variable 2numero") y lo guarde en la variable "n". Alguien podría objetar, por qué no uso la misma variable número para transferir el argumento, en vez de pasar el valor de una variable a otra. Esto es por recalcar la naturaleza independiente de las funciones. La función "cubo" podríamos tenerla definida y guardada en otro programa, y no tendríamos más que recortarla y pegarla al final de nuestro nuevo programa para poder hacer uso de ella. La transferencia entre el argumento pasado en "numero" y la variable "n" que lo recibe es automática. Si tuviéramos una función con más de un argumento, por ejemplo la siguiente: "nombre(argumento1,argumento2)", en su definición nosotros tendríamos que escribir, para ser exactos, lo siguiente:
Para transferir los argumentos, a la variable n y m en el mismo orden en que se declaran, es decir, "n" será igual al primer argumento, y "m" será igual al segundo. Volviendo a nuestro programa, la siguiente línea es ya el cuerpo de la función:
El código de la función en este caso es lo más pequeño que puede ser. Una función puede ser tan complicada como se quiera, pero en este caso, todo el trabajo se hace en esta línea. Todas las funciones deben terminar con la instrucción "return" que termina la ejecución de su código, y devuelve como ya he dicho, el control a la línea siguiente a la que la llamó. Si la instrucción "return" tiene alguna expresión después en la misma línea, el ARexx la evalúa y devuelve su valor al punto donde se llama. En este caso "return" tiene la expresión "n**3". Esto es una operación matemática. El operador "**" es el de exponenciación, así que "n**3" significa lo mismo que "cogeel valor de n y elévalo al cubo". Una vez evaluado, "return" devuelve el valor calculado a la línea de la llamada de "cubo". Si recordamos esa línea era:
De esta forma queda claro ahora, como el resultado devuelto por "cubo" queda almacenado en la variable "resultado". En este momento es muy posible que alguien vuelva a preguntarse si es realmente necesaria la definición de una función para una operación tan sencilla. Pues bien, debo confesarles que evidentemente no es necesaria, si lo he hecho así, ha sido por motivos didácticos, con el fin de explicar un buen número de características del ARexx en un solo listado. El programa funcionaría de manera similar (pruébenlo) si eliminamos todas las líneas de la definición de "cubo" y adicionalmente cambiamos la línea de llamada a la función por:
Como pueden ver, la operación de elevar al cubo el valor de la variable "numero", se realiza sin problemas en un solo paso, en la misma línea. Mas adelante veremos ejemplos de tareas más complicadas que cuadran mejor con la necesidad de definir una función. De momento, baste este ejemplo para ilustrar las generalidades del ARexx, aunque comprendo que introduce muchos términos nuevos que pueden resultar confusos para los no iniciados en programación. En próximos capítulos prometo insistir en muchos de los aspectos vistoshoy, pero de momento lo único que puedo sugerir es que intenten experimentar con modificaciones del programa, tal y como decía al comienzo. Por ejemplo, otra modificación útil, es alterarlo para que realice otro tipo de operaciones matemáticas solicitando del usuario, no uno, sino dos datos con los que operar. Las expresiones en ARexx admiten los operadores aritméticos normales: "+" suma, "-" resta, "*" producto, "/" división, "%" división entera o módulo, "//" resto y "**" exponenciación. Además asmite expresiones complicadas como paréntesis anidados. Con estos operadores básicos se pueden realizar muchas variaciones funcionales de nuestro pequeño programa. Otras operaciones más complejas como logaritmos o trigonométricas, también están soportadas, pero forman parte de la librería de funciones estándar que prontoveremos. En fin, una vez más termino, despidiéndome de ustedes con la confianza de que vuelven a estar con nosotros el próximo mes. Hasta pronto a todos los ARexx usuarios. |
| Envía esta página web a un amigo: Esta opción está desactivada temporalmente, rogamos disculpen las molestias |
|