Volver menú revistas Volver página anterior

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.

N° 7- Febrero 1990
Amiga World

TREPA CON A-REXX


Por Santiago Estrada

Si no la conocen
todavía, ya es hora
de que incluyan en su
vocabulario esta
palabra, REXX, que
seguramente procede
de la latina "REX", en
castellano, REY.

Todo el mundo en la llamada comunidad del Amiga (fuera de nuestras fronteras) habla ya de REXX. El que reciba o compre revistas extranjeras, comprobará que no se puede leer una revisión de un producto sin que se indique si soporta o no soporta REXX. Parece ya confirmado que la mismísima Commodore lo incluirá sin cargo adicional como el AmigaBasic, en la versión 1.4 del sistema operativo.

Y es que el REXX, al igual que su casi tocayo el tiranosaurio REX del período cretácico, es el nuevo dominador de la serva multitarea del Amiga. Yo diría en broma que es el dominador común de todas las tareas, pues todas, desde el más humilde y sencillo editor de fuentes hasta el más altivo y complejo CAD/CAM 3D, se someten a los comandos de este oscuro monarca de las sombras que permanece en la memoria del Amiga.

El REXX es, fundamentalmente, un lenguaje de programación a mitad de camino entre el BASIC y el C, que se diseño en principio para grandes ordenadores por Michael Cowlishaw.

Es un lenguaje especializado en el manejo de tiras de carácteres (strings) y en el reconocimiento de comandos y sus parámetros que, en definitiva, es una potente herramienta para la construcción de nuevos comandos a partir de los comandos de otras utilidades. A un comando construido se le suele llamar 'Macro' y a los programas AREXX se les suele llamar, por extensión, MACROS (el término 'macro' procede de los ensambladores donde una macro es una nueva instrucción definida a partir de otras instrucciones).

La implementación en el Amiga, es decir, el 'AREXX' o, para entendernos, el 'Amiga REXX', se ha llevado a cabo por William S. Hawes, muy popular por ser el creador, entre otras cosas del ConMan y WShell. Parece, por cierto, que todas las cosas que hace Mr. Hawes terminan siendo un estándar en el Amiga: la mayor parte de las mejoras al 'CLI' incorporadas por el 'Shell' del 1.3, ya se encontraban en los productos antes citados de Mr. Hawes.

Muchos de ustedes tendrán ya experiencia con lenguajes de macros, ya que muchas utilidades como procesadores de texto, hojas de cálculo e incluso programas de animación, llevan incorporado un lenguaje de MACROS propio. El mismo AmigaDos contiene el comando 'EXECUTE' y sus satélites ('IF', 'LAB', 'SKIP', etc.) que sirven para ejecutar, con un solo comando, una secuencia de otros comandos (o sea una MACRO o, en términos de AmigaDos, una 'script de execute'). El disco EXTRAS del sistema operativo contiene, desde la versión 1.3, un buen 'editor de fuentes', el EMACS, que incorpora un lenguaje de MACROS muy simple pero muy útil.

Otro lenguaje de programación más, se preguntarán todos los que, como yo mismo, están ya un poco hartos del BABEL de lenguajes informáticos. Pues si, un lenguaje más, pero con una serie de características que lo hace único y, para nosotros, los usuarios del Amiga, de incalculable valor en mi opinión.

Vamos a ver cuáles son las características que han conferido al AREXX el honor de codearse de igual a igual con el omnipresente BASIC en el futuro disco EXTRAS de la versión 1.4 (si es que su regia majestad, el AREXX, no exige un disco exclusivo para él y su amplia corte de librerías y ejemplos).

Lo que, en primer lugar, convierte al AREXX en único es que define una 'interfaz' muy sencilla (basada en el sistema de 'mensajes' y 'puertos' del EXEC del Amiga) para que todos los productos que así lo deseen comuniquen con él.

Si un programador de un producto desea que éste pueda comunicar con AREXX, solamente tiene que utilizar unas 'estructuras' y 'funciones' en la misma forma que se usa la 'graphics.library' o la 'intuition.library'. A partir de ese momento, el producto podrá 'lanzar' o 'ejecutar' MACROS de AREXX, y recibir comandos desde ellas

Es decir, lo que convierte a AREXX en 'único' es eso precisamente, aunque resulte 'perogrullesco', que sea único. Su poder crece en la medida en que todos los productos que quieran incorporar un lenguaje de MACROS utilicen su 'interfaz' en lugar de dedicarse a construir un nuevo lenguaje.

De ello, se derivan, a mi entender, las siguientes ventajas:

  1. Los usuarios sólo tenemos que aprendernos un único lenguaje de MACROS en lugar de uno distinto para cada producto.
  2. Los programadores se pueden concentrar en diseñar su producto y olvidarse de diseñar otro lenguaje de macros (reinventar la rueda) para que su producto sea programable y versátil. La consecuencia es que se pueden obtener productos de mayor calidad en menos tiempo y, por lo tanto, con menor coste.


  3. Al reunir AREXX todos los posibles lenguajes de MACROS en uno sólo ocupa, lógicamente, menos espacio que todos ellos por separado. De esta forma se consigue que la ocupación en memoria y el tiempo de carga de los productos que usen AREXX será menor que si incorporara cada uno su propio lenguaje de MACROS (a mí me ocupa menos ya, en conjunto, que toda la parafernalia de comandos del EXECUTE, tanto en disco como en memoria).


  4. Uno de los defectos de los lenguajes de macros que incorporan los productos es que suelen ser muy simples: los hay sin instrucciones de control de flujo y, si las tienen, les faltan las variables, o viceversa. EL lenguaje de MACROS del AmigaDos, por ejemplo, no tiene ciclos (hay que simularlos) y, hasta la versión 1.3, no tenía variables, pero las que ahora tiene sólo se pueden usar en los comandos 'IF' y 'MORE' (con esto no pretendo decir que sea malo: algunos son peores). El AREXX, sin embargo, debido a que sus creadores se han concentrado en la tarea específica de hacer un lenguaje de macros, es tan potente que, en mi opinión, iguala a la de muchos lenguajes de programación tradicionales.


  5. AREXX puede ser, para los programadores, una especie de generador de 'prototipos' y 'juegos de ensayo' que puede facilitar mucho el desarrollo y la implementación final de los productos. La consecuencia es, otra vez, el consabido 'bueno, bonito, barato'.

Supongo que a estas alturas, si he logrado su interés, querrán ver algún ejemplo. En el directorio 'EXAMPLES' del disco en el que se distribuye AREXX hay muy buenos ejemplos, pero, en este artículo de introducción, prefiero presentar un ejemplo que, no siendo demasiado complejo, permita hacerse una idea de la potencia del lenguaje.

Para ello he escogido una versión reducida de una MACRo hecha por mí mismo y que uso con bastante frecuencia (la que yo uso tiene más funciones, pero es demasiado compleja para primer ejemplo). Este MACRO, además envía comandos a algo que tiene todo el mundo que posee un Amiga: el AmigaDos. para que comprendan lo que hace la MACRO primero explicaré el problema que trata de solucionar.

Muchas veces necesitamos realizar un comando de AmigaDos (Copy, Delete, More, Rename, etc.) en un conjunto de directorios y ficheros. Cuando los nombres de esos ficheros tienen alguna característica común (empiezan o terminan por los mismos caracteres, etc.) podemos utilizar los 'modelos' o 'patrones' del AmigaDos que son muy potentes y que, ahora, en la versión 1.3, con los 'scripts' SPAT y DPAT del directorio 'S' del disco WorkBench podemos emplear con casi cualquier comando.

El problema empieza cuando queremos realizar un comando sobre un grupo de directorios o ficheros cuyos nombres no tienen ningun 'modelo' de caracteres en común.

Una solución consiste em utilizar el WorkBench seleccionando en los 'Drawers' los 'Projects' y 'Tools' que deseemos pero, desgraciadamente, hasta la versión 1.4, el WorkBench sólo maneja ficheros con un '.info' asociado y, por otro lado, el WorkBench no realiza todas las funciones del AmigaDos.

Otra solución consiste en emplear una utilidad que recorra, transverse o, literalmente, 'trepe' por el árbol de directorios preguntandonos, para cada fichero, si queremos ejecutar un comando sobre él. Esto último es lo que hace, por ejemplo, el comando 'DIR' de AmigaDos con la opción I (de Interactivo), pero solamente nos permite ejecutar, en cada fichero, los comandos 'TYPE' y 'DELETE'.

Al igual que 'DIR', todas las utilidades que conozco, siempre les falta alguna que cosa que yo deseo hacer: si copian, no muestran, si muestran, no copian y, si muestran y copian, ni renombra, ni eliminan, pero, el caso de que hagan de todo (como Atree o Sid), apenas me caben en mis 512K.

Por lo cual, cuando compré mi versión de AREXX, me decidí a hacer una MACRO que emulara el comportamiento de 'DIR' interactivo haciendo de todo. La MACRO se llama 'TREPA.REXX' porque sirve para trepar por el árbol de directorios del AmigaDos y, para cada fichero que encuentra, nos pregunta si queremos tartarlo o no.

TREPA.REXX se usa desde el CLI o SHELL ejecutando un comando con el siguiente formato:

rx trepa <comando> <árbol> <opciones>

donde

'rx' es el lanzador, desde AmigaDos de MACROS AREXX.

'trepa' es el nombre de la MACRO.

<comando> es el comando a ejecutar (primer parámetro obligatorio)

<árbol> es el árbol (directorio o fichero) a trepar (segundo parámetro opcional, si no ponemos nada se toma el directorio actual).

<opciones> con las opciones del comando a ejecutar si las tiene (tercer parámetro opcional).

Por ejemplo, si quisiéramos recorrer el directorio del volumen introducido en 'DF0', copiando selectivamente ficheros al disco 'ram:', podríamos ejecutar el siguiente comando:

rx trepa copy df0: to ram:

En este caso concreto la MACRO comenzará a 'trepar' por el Arbol de directorios de 'df0:' y, para cada fichero, nos preguntará si queremos copiarlo al disco 'ram:'.

Supongo que el listado de TREPA.REXX adjunto parecerá un galimatías, pero eso sucede con todos los lenguajes cando no se conocen. Los comentarios al listado están pensados para personan que tengan alguna experiencia en programación. No recomiendo su lectura a persona que no tengan esa experiencia, ya que están pensados para comparar, en la medida de lo posible, el AREXX con el BASIC y el C y, en ningún caso, pretenden servir para enseñar AREXX.

Todo lo dicho hasta ahora no explica suficientemente porqué AREXX es una candidato para el disco de EXTRAS de la versión 1.4 del sistema operativo. Lo que, en mi opinión, hace que el AREXX sea tan útil es que puede convertirse en una 'central de comunicaciones' entre todas las tareas del AMIGA que soporten su interfaz.

De la idea de un lenguaje de MACROS independiente de cualquier producto a la idea de un lenguaje de MACROS que comunique simultánemante con todo los productos en una máquina multitarea no hay mucho trecho que recorrer (una vez inventado parece fácil).

El AREXX, como central de comunicaciones, se encarga de recibir diligentemente los comandos, los distribuye a sus destinatarios para que los ejecuten y, atendiendo al remite, envía las REXXpuestas.

Para comunicarse, las MACROS de AREXX utilizan el concepto de HOST. En cada momento, toda MACRO tiene una tarea del Amiga que es su HOST. A esta tarea HOST es a la que, si no se especifica otra cosa, se envían los comandos. Una MACRO puede realizar, por ejemplo, la siguiente secuencia:

  1. Recibir, junto con unos parámetros, un comando del HOST actual.


  2. Cambiar de HOST y, de acuerdo con el contenido de los parámetros, enviarle un comando.


  3. Recibir una respuesta del nuevo HOST para, por último, volver al HOST inicial e indicarle el resultado de su comando.

Las secuencias de intercambio entre los HOST y la MACRO pueden llegar a ser todo lo complejas que se quieran.

Un HOST, para los entendidos, es cualquier 'Port' del sistema de mensajes del EXEC definido para comunicarse con AREXX. Cuando una tarea, desde un 'Port', lanza una MACRO (con un mensaje al monitor de AREXX), se convierte automáticamente en el HOST implícito o por defecto.

Si no entienden lo anterior no se preocupen, porque vamos a ver un ejemplo.

No será extraño que una vez que el AREXX esté instalado en el AMIGA el procesador de textos te pida 'favores' a la hoja de cálculo para que realice tareas que él no puede hacer.

Si estuviéramos, por ejemplo, escribiendo con un procesador de textos un informe de previsiones de gasto para el mes de febrero, ncesitaremos insertar en el informe los resultados que nos da una hoja de cálculo.

Para insertar el informe de la hoja de cálculo en el texto tendríamos, como poco, que cambiar a la ventana de la hoja de cálculo, teclear los comandos para cargar la hoja de previsiones, calcularla y escribir el resultado en el disco 'RAM:' o 'RAD:', cambiar de nuevo a la ventana del procesador de textos y, por último, insertar el fichero generado con un comando u opción del procesador de textos.

Si, en cambio, tuviéramos AREXX y nuestro procesador de textos y hoja de cálculo soportaran su interfaz, lo único que tendríamos que hacer es ejecutar, desde el procesador de textos, el comando 'PREVISIONES 2' para que, en poco tiempo, después de un par de gruñidos de la disquetera, apareciera la previsión de gastos del mes de febrero inserándose línea a línea en nuestro texto.

Para ver cómo se haría una MACRO que haga esto posible (con un procesador de textos y hoja de cálculo ficticios) se puede examinar el segundo listado con el fuente de la macro PREVISIONES.REXX y su comentarios.

No sé si el anterior ejemplo da una idea exacta de la potencialidad de un mensajero programable capaz de comunicar cualquier tarea con otra en el sistema. Pero dejando volar la imaginación, las posibilidades que se abren son infinitas.

Hay quien dice, por ejemplo, que el AREXX es la respuesta del Commodore Amiga al HYPERTEXT del Apple Macintosh, calificándolo de auténtico HYPERMEDIA ya que, con AREXX, no solamente podemos referenciar texto a través de un texto, sino cualquier medio a través de otro (texto con sonidos, imagen y animación).

El AREXX es como un gurú (me refiero a un 'maestro' y no al aborrecido mensaje que todos padecemos) que puede sacar lo mejor que cada uno lleva dentro: el procesador de texto que procese texto, el programa de dibujo que dibuje, la hoja de cálculo que calcule o, como se suele decir, "zapatero a tus zapatos".

Creo que la capacidad multitarea del Amiga, junto con su capacidad de expansión (sobre todo en memoria) y el broche final del AREXX, precipitará el final de la era de esos 'paquetes integrados' (esos 'BRONTOSAURIOS' enormes y lentos) que hacen de todo y todo lo hacen mal: el AREXX los exterminará.

Opino también que AREXX causará la bendita desaparición de todos esos elnguajes de macros que proliberan por todas las utilidades al objeto de hacerlas programables y versátiles, pero que terminan haciéndolas innecesariamente complejas, lentas y enormes.

El mejor ejemplo que conozco de lo anterior es la utilidad de base de datos MicroFiche Filer Plus. Esta utilidad es una base de datos hecha a la medida del Amiga y completamente distinta de todas las utilidades de base de datos en boga.

El MicroFiche Filer Plus pone el acento sobre la visualización de los datos y no sobre su almacenamiento y procesamiento: está hecha para ver los datos. No es el momento de hacer una revisión de MicroFiche Filer Plus, pero, en mi opinión, puede llevarse el 'Oscar' a 'la utilidad más original concebida de una sola vez' desde el advenimiento, hace ya tiempo, del Visicalc (la Eva de todas las hojas de cálculo).

La primera versión de MicroFiche Filer (sin Plus) no era programable. La versión PLUS soporta AREXX y, por lo tanto, es totalmente programable. Es decir, con una mínima ocupación en disco y memoria tenemos una utilidad, única en su género, mucho más potente que otros pesos pesados del mismo ramo que, además, es mucho más barata.

Hay un par de cuestiones que supongo de interés y que creo que no quedan suficientemente aclaradas. La primera es qué utilidad tiene el AREXX para usuarios no programadores. Para los no programadores el AREXX puede dar sus servicios de la misma forma que el lenguaje C, es decir, mediante macros hechas por otros. La diferencia con el C es que, al ser AREXX un intérprete, se necesita poseer AREXX y ejecutar su MASTER para poder utilizarlo.

La segunda cuestión es para programadores: dominando AREXX podemos olvidarnos del BASIC y podemos olvidarnos del C o de un lenguaje parecido como el Modula o el Pascal. La respuesta depende de cuáles sean nuestros objetivos de programación.

El AREXX sirve de apoyo a la programación de productos pero solamente desvirtuándolo podríamos utilizarlo para desarrollar un producto completamente con él (que no sea, claro está, un conjunto de MACROS de AREXX). Para los que desarrollan productos de utilidad, digamos, pública, el AREXX es solamente un complemento ideal para el producto a la hora de ejcutarlo y una ayuda a la hora de desarrollarlo.

Para aquellos usuarios que sólo programan de forma casual para hacer pequeñas utilidades de valor particular creo que AREXX es su herramienta ideal. Yo antes usaba el BASIC para esas tareas y el C para las cosas serias. Ahora uso AREXX para las cosas sencillas y, gracias a su capacidad, el ensamblador para las cosas serias. El conjunto ASSEMBLER/AREXX de ahora me resulta mucho más ágil y, a la vez, más potente e integrado que el conjunto C/AmigaBasic.

Si lo que se necesita es una 'Primera Lengua' para aprender a programar el AREXX está especialmente recomandado para ello y, además, los programadores de AREXX están bastante solicitados para trabajar en entornos de grandes ordenadores compatibles.

CLAVES A-REXX
(Para facilitar la comprensión todas las palabras clave de AREXX estan en mayúsculas pero
no es necesario que sea así).

La MACRO está basada en una función 'recursiva' (que se utiliza a si misma) ya que un árbol es una estructura de datos que se define de forma recursiva: un árbol es, bien una estructura vacía, o bien un número finito de estructuras de árbol denominadas 'subárboles' del árbol. No voy a teorizar más sobre el tema, que supongo conocido, y paso a comentar las líneas del listado de TREPA.REXX

- En AREXX todo lo que está necerrado entre '/*' y '*/', al igual que en 'C', es un comentario. Tradicionalmente las MACROS de AREXX (como los programas BASIC) comienzan por un comentario que sirva para documentar las tareas que realiza, pero en AREXX esto es lago más que una trdición, si la primera línea del fichero no es un comentario, el intérprete no lo identificará como una MACRO de AREXX.

- Con las instrucciones ARG recogemos, con facilidad pasmosa, los parámetros que hemos pasado en la llamada a la MACRO separados por espacios (esto se explica más adelante a propósito de la instrucción PARSE).

Notar que en AREXX, al igual que en AmigaBasic y al contrario que en C, no se declaran previamente las variables. Eso sí, hay dos diferecias con el BASIC: primero, si una variable no está inicializada su valor no es nulo como en BASIC, sino que toma el propio nombre de la variable y, segundo, las variables no tienen 'tipo', el AREXX no distingue entre 'enteros', 'reales', 'tiras', etc., para el AREXX, en realidad, todos son tiras, y, si una tira contiene un número correcto, entonces puede tratarse con los operadores matemáticos.

- Llamamos a una función 'STATEF', de la 'rexxsupport.library' que nos devuelve una tira con las características del árbol (si es directorio o fichero, octetos y/o bloques que ocupa, el comentario de 'FILENOTE', etc.) y extraemos de esa tira la primera palabra con la función WORD para almacenarla en la variable TIPO (la primera palabra es 'DIR' si el árbol es un directorio, 'FILE' si es un fichero y nada si no existe).

- La instrucción SELECT es igual a la SWITCH de 'C' y su equivalente en AmigaBasic es un IF con ELSEIF's. Con la SELECT, de acuerdo con el valor de Tipo, nos dirigimos a trepar por un directorio llamando a la función recursiva Trepar, a tratar un fichero con la función Tratar o, si no existe el árbol pedido en la llamada, a enviar un mensaje de error al usuario con la instrucción SAY que cumple las mismas funciones que el PRINT de BASIC o el PRINTF de C.

A la vuelta de las funciones llamadas, el árbol pedido se ha tansversado o 'trepado' entero y no queda más por hacer: con la instrucción EXIT terminamos la MACRO.

Incidentalmente, como curiosidad, notar que hay que tratar de forma diferente el primer nodo del árbol de directorios debido a que puede ser una especificación de volumen (nombre seguido de ':'. A reconocer y tratar esta eventualidad están dedicadas las líneas que utilizan la función RIGHT muy parecida al RIGHT* de basic.

Notar también la cómoda forma en que trata el AREXX la concatenación de 'strings', si dos tiras están separadas por un blanco AREXX las concatena con un espacio intermedio, si están concatenadas con el operador '||' las concatena sin espacio intermedio (igual que el operador '+' de AmigaBasic). Es decir:

SAY 'separado por' 'un espacio'
visualizaría la siguiente línea en la consola:
separado por un espacio
   En cambio la siguiente instrucción
SAY 'todo' || 'junto'
visualizaría la siguiente línea:
todo junto.

- La función trepar comienza en la línea con la etiqueta (igual a las de AmigaBasic) 'Trepar:'.

La instrucción 'PROCEDURE' indica que la función es un como un 'SUBPROGRAM' de AmigaBasic o una 'FUNCTION' de C, es decir, las variables que nombremos dentro de la función no 'colisionan' con las ya nombradas en otras partes de la MACRO o, para entendernos, las variables son locales a la función: si utilizamos el mismo nombre de variable en el programa principal y en la función, el AREXX no los considerará la misma variable, a menos que la mencionemos en la lista que sigue al parámetro EXPOSE (que cumple igual función que el STATIC de AmigaBasic o el EXTERN de C).

Sin la instrucción PROCEDURE una función de AREXX es igual que el objeto de un GOSUB de BASIC (sin equivalente en C).

La instrucción ARG hace lo mismo en este caso que en el anterior: recoge los parámetros de la llamada a la función que, ahora, solamente es el 'subárbol' al que hay que 'trepar'.

- Se llama a la función Pedir (que comento en el punto 10) para saber si el usuario desea entrar o 'subir' al 'subárbol' presente: la respuesta del usuario se almacena en la variable Respuesta. Si la respuesta es distinta de 'S' Trepar retorna a la función que la llamó (ella misma o la MACRO principal), devolviendo el valor de Respuesta. Si la respuesta es 'S' entonces utilizamos la función de SHOWDIR de la librería de soporte que nos devuelve una lista de los ficheros y subdirectorios de un directorio separados, en este caso, por el carácter '/'.

- La instrucción DO FOREVER itera sin fin, ejecutando las instrucciones comprendidas entre ella y su correspondiente END. Es equivalente a una sentencia, por ejemplo, FOR (;;) en C (de la que hay que salir con un BREAK, RETURN o GOTO) o a una WHILE -1 en AmigaBasic (de la que podemos también salir con GOTO o RETURN).

- Dentro del cuerpo de la instrucción DO encontramos, en primer lugar, la misteriosa instrucción PARSE. Esta no tiene equivalente en AmigaBasic o C y es una de los potentes herramientas de AREXX para manejar comandos y sus parámetros.

/* Trepa a un Arbol AmigaDos ejecutando un comando selectivamente */ (1)
ARG Comando Arbol Opciones  (2)
Tipo=WORD(STATEF(Arbol),1)  (3)
SELECT                      (4)
WHEN Tipo=='DIR' THEN
  IF RIGHT(Arbol,1)==':' | RIGHT(Arbol,1)=='/' THEN
    CALL Trepar Arbol
    ELSE CALL Trepar Arbol || '/'
WHEN Tipo=='FILE' THEN CALL Tratar Arbol
OTHERWISE SAY 'No encuentro el arbol' Arbol 'pedido'
END
EXIT
Trepar: /* trepar al Arbol */ (5)
PROCEDURE EXPOSE Comando Opciones
ARG Arbol
Respuesta=Pedir('Entrar en directorio:' Arbol) (6)
IF Respuesta ~=='S' THEN RETURN Respuesta
Lista=SHOWDIR(Arbol,'A','/')
DO FOREVER                                     (7)
   PARSE VAR Lista Nombre '/' Lista            (8)
   IF Nombre=='' THEN
      DO
        SAY 'Terminado el directorio' Arbol 'Retrocediendo ...'
        RETURN 'N'
      END
   ELSE
      DO
        Tipo=WORD(STATEF(Arbol || Nombre),1)
        SELECT
        WHEN Tipo=='DIR' THEN
           IF Trepar(Arbol || Nombre || '/')=='R' THEN RETURN 'N'
        WHEN Tipo=='FILE' THEN
           IF Tratar(Arbol || Nombre )=='R' THEN RETURN 'N'
        OTHERWISE SAY 'No encuentro el Arbol ' Arbol || Nombre
        END
      END
END
/* Nunca devuelve control por aqui */
Tratar:                               (9)
PROCEDURE EXPOSE Comando Opciones
ARG Arbol
Respuesta=Pedir('Desea ejecutar' Comando Arbol Opciones)
IF Respuesta=='S' THEN ADDRESS COMMAND Comando Arbol Opciones
RETURN Respuesta
Pedir:                              (10)
ARG Mensaje
DO FOREVER
   SAY Mensaje
   SAY 'Conteste con una abreviatura de
Terminar/Retroceder/Si/No'
   SAY 'Si pulsa retorno se tomar "NO" por defecto'
   PULL Respuesta -
   SELECT
   WHEN ABBREV('TERMINAR' ,Respuesta,1) THEN
        DO
          SAY 'Terminado el recorrido '
          EXIT
        END
   WHEN ABBREV('RETROCEDER',Respuesta,1) THEN RETURN 'R'
   WHEN ABBREV('SI' ,Respuesta,1) THEN RETURN 'S'
   WHEN ABBREV('NO' ,Respuesta,0) THEN RETURN 'N'
   OTHERWISE SAY 'Entre una respuesta de las indicadas, gracias'
   END
END

La instrucción PARSE provee un mecanismo para extraer una o más subtiras de una tira y asignarlas a variables. La tira de entrada puede venir de varias fuentes: una expresión o variable, la llamada a una MACRO o función (la instrucción ARG es en realidad una PARSE ARG) o cualquier expresión o variable (como en el caso presente). La sintaxis de PARSE es la siguiente:

PARSE [UPPER] TiraFuente [Patrón] [,Patrón] ...

El parámetro UPPER, si se incluye, convierte a mayúsculas la subtiras extraídas de TiraFuente antes de trasladarlas a las variables indicadas por los patrones.

El patrón es, a la vez, una manera de indicar las variables que van a recibir las subtiras y de indicar cómo se forman estas últimas. Hay varias formas de indicar cómo se forman las subtiras, pero la principal es que una variable se llena con todos los carácteres de la tira fuente hasta que se encuentra un caracter específico. En la instrucción PARSE del ejemplo se emplea una '/' como separador para la subtira que irá a la variable Nombre, el resto de la tira fuente se lleva sobre lista.

El efecto final de la instrucción PARSE del ejemplo es que obtenemos en la variable 'Nombre' el nombre del primer fichero o subdirectorio de la lista, al mismo tiempo que quitamos de Lista este nombre dejando el resto.

Notar que la instrucción ARG empleada antes es en realidad una PARSE ARG y lleva sobre las variables que se indican las sibtiras separadas por espacios de la llamada a la MACRO o la función interna.

Cuando en 'Nombre' obtengamos una tira nula después del PARSE es que se ha acabado la lista de ficheros y directorios del nodo presente y retornamos al anterior.

Si 'Nombre' contiene algo examinamos, igual que en la parte principal de la MACRO, si es fichero o directorio y procedemos, mediante una SELECT para enviar un mensaje de error cuando no exista un nombre de la lista que acabamos de obtener: en un sistema multitarea como el del Amiga uno nunca puede estar seguro de que en el intervalo, desde que se obtiene la lista hasta que se comprueba el nombre, alguna otra tarea no haya eliminado el nombre.

- La función Tratar es la que se encarga de ejecutar el comando pedido sobre un fichero. Primero pregunta al usario si desea ejecutar el comando para ese fichero y, en caso afirmativo, lo intenta ejecutar. La instrucción ADDRESS COMMAND envia la expresión formada detrás de ella al AmigaDos para que la ejecute.

- La función Pedir no tiene mucho que comentar. Visualiza un mensaje de petición con instrucciones para el usuario que pueda responder con Sí, No, Terminar -que se comentan ellas solas- y Retroceder, que significa que queremos terminar con el recorrido del árbol presente y retomar al anterior.

Hay que destacar la función ABBREV que devuelve un valor Booleano cierto si la variable Respuesta contiene una abreviatura válida de cada una de las posibles contestaciones hasta el número de caracteres indicado (uno en todas, excepto en 'No', que admite la tira nula como abreviatura).


Volver menú revistas Volver página anterior