NetREXX

NetREXX
Información sobre la plantilla
Parte de la familia Lenguajes de Programación NetREXX
NetREXX.jpg
NetREXX LP NetREXX

NetREXX es un nuevo lenguaje de programación derivado de Rexx y Java (tm); es un dialecto de Rexx que retiene la portabilidad y eficacia de Java, a la vez que es tan fácil aprender y usar como Rexx.

Introducción

NetRexxes una alternativa efectiva al lenguaje Java. Con NetRexx, puede crear programas y applets para el entorno Java más fácilmente que programando en Java. Usar clases Java es especialmente fácil en NetRexx de modo que raramente tiene que preocuparse por todos los tipos diferentes de números y strings que Java requiere. Este documento presenta las características principales de NetRexx, y está pensado para ayudarle a comenzar a usarlo rápidamente. Se asume que tiene algún conocimiento de programación en lenguajes tales como Rexx, C, BASIC o Java, pero no son necesarios conocimientos de programación orientada a objetos.

Programas NetRexx

La estructura de un programa NetRexx es extremadamente simple. Este programa ejemplo, 'toast', está completo, documentado, y su ejecución es la que se muestra:

/* Esto le desea la mejor salud.*/

say 'Cheers!'

Este programa consta de dos líneas: la primera es un comentario optativo que describe el propósito del programa, y la segunda es una sentencia SAY. SAY simplemente visualiza el resultado de la siguiente expresión -- en este caso sólo un string literal (puede usar comillas simples o dobles para entrecomillar los strings, como prefiera). Para ejecutar este programa, edite un fichero llamado toast.nrx y copie o pegue las dos líneas anteriores en él. Puede entonces usar el programa Java NetRexxC para compilarlo, y el mandato java para ejecutarlo:

java COM.ibm.netrexx.process.NetRexxC toast java toast

Tiene también la posibilidad de poder utilizar el comando NETREXXC para compilar y ejecutar el programa con un único mandato (los detalles pueden variar -- vea el documento de instalación y guía de usuario):

netrexxc toast -run Por supuesto, NetRexx puede hacer más que simplemente visualizar un string de caracteres. Aun cuando el lenguaje tiene una sintaxis simple y un reducido número de declaraciones de tipo, es potente; el lenguaje permite un acceso completo a la rápidamente creciente colección de programas Java conocida como 'librería de clases', así como que sean escritas nuevas librerías de clases en NetRexx. El resto de este documento presenta la mayoría de de las características de NetRexx. Dado que la economía, poder, y claridad de expresión de NetRexx se aprecia mejor con el uso, le insto a que intente probar a usar usted mismo el lenguaje.

Expresiones y variables

Como SAY en el ejemplo 'toast', muchas sentencias en NetRexx incluyen expresiones que serán evaluadas. NetRexx provee operadores aritméticos (incluyendo división de enteros, resto (o módulo), y operadores de potenciación), varios operadores de encadenamiento, operadores de comparación, y operadores lógicos. Estos pueden usarse en cualquier combinación dentro de una expresión NetRexx (con tal que, por supuesto, los valores de los datos sean válidos para esas operaciones) Todos los operadores actúan sobre cadenas de caracteres (conocidas como strings Rexx), que pueden ser de cualquier longitud (típicamente limitadas solamente por la cantidad de espacio de almacenamiento disponible). Las comillas (ya sean simples o dobles) se usan para indicar cadenas literales, y son opcionales si la cadena literal es un número. Por ejemplo, las expresiones:


'2' + '3' '2' + 3 2 + 3 devolverían todas '5'.

Los resultados de expresiones son frecuentemente asignados a variables, usando una sintaxis de asignación convencional:

var1=5 /* asigna '5' a var1 */ var2=(var1+2)*10 /* asigna '70' a var2 */

Puede escribir los nombres de variables (y palabras reservadas) en cualquier mezcla de mayúsculas y minúsculas que prefiera; el lenguaje no es sensible a mayúsculas y minúsculas. El siguiente programa ejemplo, 'greet', muestra expresiones utilizadas de varias maneras:

/* Un programa corto para saludarle. */ /* Primero visualizar un indicador: */ say 'Por favor teclee su nombre y entonces pulse ENTER:' answer=ask /* Obtener la respuesta en ANSWER */ /* Si no se introdujo ningún nombre, entonces usar un saludo fijo, */ /* en otro caso mostrar el del nombre cortesmente. */ if answer= then say 'Hola Extraño!' else say 'Hola' answer'!'

Tras visualizar un indicador, el programa lee una línea de texto del usuario ('ask' es una palabra reservada proporcionada por NetRexx) y la asigna a la variable ANSWER. Esta se prueba entonces para ver si ha sido introducido cualquier carácter, y se toman en consecuencia diferentes acciones; si el usuario tecleó 'Fred' por respuesta al indicador, entonces el programa visualizaría:

Hola Fred!

Como ve, la expresión en la última sentencia SAY (visualizar) encadenaba el string 'Hola' al valor de la variable ANSWER con un espacio en blanco entre ellos (el espacio en blanco es aquí un operador válido, significa 'concatenar con espacio'). El string '!' es entonces encadenado directamente al resultado construido hasta ahí. Estos modestos operadores (el operador de espacio en blanco y demás) para encadenamiento son muy naturales y sencillos de usar, y hacen la construcción de cadenas de texto simple y clara. El esquema de declaraciones es muy flexible. En 'greet', por ejemplo, la sentencia IF podría implementarse de diversas maneras, según preferencia personal. Los cambios de línea pueden ser añadidos a cualquier lado del THEN (o siguiendo al ELSE). En general, las sentencias se finalizan con el fin de una línea. Para continuar una sentencia en una línea siguiente, puede usar un guión (signo menos) tal como se hace en Inglés: say 'Aquí tenemos una expresión que es bastante larga, por tanto' - 'está dividida en dos líneas'

Esto actúa como si las dos líneas fueran una línea, con el guión y cualquier espacio en blanco alrededor siendo reemplazado por un solo espacio en blanco. El resultado neto es dos strings encadenados juntos (con un espacio en blanco en medio) y entonces visualizado. Cuando se desee, las sentencias múltiples pueden ser situadas en una línea con la ayuda del separador punto y coma:


if answer='Sí' then do; say 'OK!'; exit; end (mucha gente encuentra las sentencias múltiples en una línea difíciles de leer, pero algunas veces es conveniente).

Sentencias de control

NetRexx proporciona una selección de sentencias de control, cuya forma se eligió por legibilidad y semejanza a lenguajes naturales. Las sentencias de control incluyen IF... THEN... ELSE (como en el ejemplo 'greet') para proceso simple condicional:

if ask='Sí' then say "Ha contestado Sí"

else say "No contestó Sí"

SELECT... WHEN... OTHERWISE... END para seleccionar de entre un número de alternativas: select when a>0 then say 'mayor que cero' when a<0 then say 'menor que cero' otherwise say 'cero' end DO... END para agrupar: if a>3 then do say 'A es mayor que 3; se le asignará cero' a=0 end y LOOP... END para repetición: loop i=1 to 10 /* repite 10 veces; I varía desde 1 hasta 10 */ say i end

La sentencia LOOP puede usarse para ir dando valores a una variable hasta (TO) algún límite, por (BY) algún incremento, para (FOR) un número específico de iteraciones, y mientras (WHILE) o hasta (UNTIL) que se satisface alguna condición. También se proporciona LOOP FOREVER. La ejecución de un bucle puede ser alterada por sentencias LEAVE e ITERATE que reducen significativamente la complejidad de muchos programas.

Aritmética NetRexx

Las cadenas de caracteres en NetRexx son usadas comunmente para la aritmética (asumiendo, por supuesto, que representan números). La representación de cadenas de números puede incluir enteros, notación decimal, y notación exponencial; todos son tratados de la misma manera. Estos son un pocos:

'1234' '12.03' '-12' '120e+7'

Las operaciones aritméticas en NetRexx están diseñadas para personas más que para máquinas, por tanto son decimales más que binarias, no se desbordan con ciertos valores, y siguen las reglas que las personas usan para la aritmética. Las operaciones están completamente definidas para Rexx por el standard ANSI, así las implementaciones correctas siempre darán los mismos resultados. Una característica excepcional de la aritmética de NetRexx es la declaración NUMERIC: puede emplearse para seleccionar la precisión arbitraria de los cálculos. Puede calcular a cualquier precisión que desee, quizá para cálculos financieros, limitado solamente por la memoria disponible. Por ejemplo:

numeric digits 50 say 1/7 Lo que mostraría en pantalla 0.14285714285714285714285714285714285714285714285714

La precisión numérica puede ser fija para un programa entero, o ajustarse a voluntad dentro del programa. Se puede usar también la declaración NUMERIC para seleccionar la notación (científica o de ingeniería) utilizada por los números en formato exponencial.


NetRexx también proporciona acceso simple a la aritmética binaria nativa de los ordenadores. Usar aritmética binaria ofrece muchas oportunidades para cometer errores, pero es útil cuándo se quiere que las prestaciones sean superiores. Se selecciona aritmética binaria si agrega la declaración:

options binary

al principio de un programa NetRexx. El procesador del lenguaje usará entonces aritmética binaria en lugar de aritmética decimal Rexx para los cálculos, en todas partes del programa.

Trabajando con cadenas

Otra cosa para la que Rexx es bueno es para manipular cadenas de varias maneras. NetRexx provee de los mismos medios que Rexx, pero con una sintaxis que es más parecida a la de Java u otros lenguajes similares:


phrase='Ya es hora para una fiesta' say phrase.word(7).pos('r')

Aquí la segunda línea puede ser leída de izquierda a derecha como "toma la variable 'phrase', encuentra la séptima palabra, y entonces localiza la posición de la primera 'r' en esa palabra". Esto visualizaría '3' en este caso, porque 'r' es el tercer carácter en 'party'. (En Rexx, la segunda línea anterior se hubiera escrito usando llamadas anidadas a funciones: say pos('r', word(phrase, 7))lo que no es tan fácil de leer; hay que seguir el anidamiento y entonces volver (hacer backtracking) de derecha a izquierda para averiguar exactamente de que se trata.)


En la sintaxis NetRexx, en cada punto de la secuencia de operaciones alguna rutina actúa sobre el resultado qué se ha obtenido antes. Estos subprogramas se llaman métodos (method), para hacer la distinción con las funciones (que actúan aisladas). NetRexx provee (como métodos) de la mayoría de las funciones que fueron incluídas para Rexx, por ejemplo:

changestr (cambia todas las ocurrencias de un substring a otro) copies (crea copias múltiples de un string) lastpos (encuentra la ocurrencia de más a la derecha) left y right (devuelven el carácter del extremo izquierdo/derecho) reverse (invierte, cambia de fin a fin) space (rellena entre palabras con espaciado fijo) strip (borra el espacio en blanco de cabeza y/o cola) pos y wordpos (encuentran la posición de string o una palabra en un string) verify (comprueba el contenido de un string para caracteres seleccionados) word, wordindex, wordlength, y words (trabajo con palabras)

Estos y los otros como ellos, y el análisis descrito en la próxima sección, hacen especialmente fácil procesar texto con NetRexx.

Analizando cadenas

La sección previa describía alguna de las facilidades disponibles para el manejo de cadenas; NetRexx también proporciona el análisis de strings de Rexx, que es una forma rápida y simple de separar cadenas de caracteres usando pattern-matching simple. Una sentencia PARSE especifica primero la cadena a ser analizada, a menudo tomada simplemente de una variable. Se sigue éste de una plantilla o patrón que describe cómo se va a dividir el string, y donde se van a colocar los fragmentos.

--- Análisis en palabras --- La forma más sencilla de plantilla de análisis consta de una lista de nombres de variable. La cadena que está siendo analizada se divide en palabras (sucesiones de caracteres separadas por espacios en blanco), y cada palabra de la cadena se asigna (copia) a la siguiente variable en curso, de izquierda a derecha. La variable final se trata especialmente de modo que le será asignada una copia de lo que quede a la izquierda de la cadena original y puede por eso contener varias palabras. Por ejemplo, en:

parse 'Esto es una frase.' v1 v2 v3 se asignaría el valor 'Esto' a la variable v1, se asignaría el valor 'es' a v2, y se asignaría el valor 'una frase.' a v3.

--- Patrones literales --- Puede usarse una cadena literal en una plantilla como patrón para dividir la cadena. Por ejemplo

parse 'To be, or not to be?' w1 ',' w2 w3 w4

causaría que se analizara el string para la coma, y entonces la división se haría en ese punto; cada sección es entonces tratada exactamente del mismo modo que lo era el string completo en el ejemplo previo.

De este modo, a w1 se le asignaría 'To be', a w2 y w3 se les asignaría los valores 'or' y 'not', y se asignaría el resto a w4: 'to be?'. Observe que el mismo patrón no es asignado a ninguna variable.

El patrón puede ser especificado como una variable, poniendo el nombre de la variable entre paréntesis. Por ello las sentencias siguientes: coma=',' parse 'To be, or not to be?' w1 (coma) w2 w3 w4 tienen el mismo efecto que el ejemplo previo.


--- Patrones posicionales --- El tercer tipo de mecanismo de análisis es el patrón posicional numérico. Este funciona de igual manera que el patrón de string excepto en la sintaxis; especifica un número de columna (que debe ser absoluto o relativo, y derivado de una variable si es necesario). Pueden mezclarse patrones de cadena y patrones posicionales.

Variables indexadas

NetRexx provee de un mecanismo de indexación de variables, adaptado de las variables compuestas de Rexx. Las variables de cadena de NetRexx pueden ser referenciadas simplemente por su nombre, o también por su nombre calificado por otra cadena (el índice). Cuándo se usa un índice, un valor asociado con ese índice es o establecido o extraido; en el último caso, se devuelve el valor inicial de la variable si el índice no ha sido utilizado para asignar un valor. Por ejemplo, el programa:

dognoise='bark' dognoise['pup']='yap' dognoise['bulldog']='grrrrr' say dognoise['pup'] dognoise['terrier'] dognoise['bulldog'] visualizaría yap bark grrrrr Puede usarse cualquier expresión entre los corchetes; la cadena resultante se utiliza como índice. Se pueden usar dimensiones múltiples, si es necesario: dognoise='bark' dognoise['spaniel', 'brown']='ruff' say dognoise['spaniel', 'brown'] dognoise['terrier'] Lo que mostraría en pantalla ruff bark Aquí va un ejemplo más complejo, un programa de prueba con una función (denominada método constante en NetRexx) que elimina todas palabras duplicadas de un string de palabras:

/* justonetest.nrx -- prueba la función justone. */

say justone('to be or not to be') /* prueba simple */ exit

/* Esto elimina palabras duplicadas de un string, y */

/* muestra el uso de una variable (HADWORD) que es */

/* indexada por datos arbitrarios (palabras). */

method justone(wordlist) constant

hadword=0 /* muestra todas las palabras posibles como nuevas */

outlist= /* inicializa la lista de salida */

loop while wordlist\= /* ciclar mientras tengamos datos */

/* después, dividir WORDLIST en primera palabra y resto */

parse wordlist word wordlist

if hadword[word] then iterate /* ciclar si tenía palabra */

hadword[word]=1 /* recordar que hemos tratado esta palabra */

outlist=outlist word /* agregar palabra a lista de salida */

end return outlist /* finalmente devolver el resultado */

Ejecutando este programa se visualizarían exactamente las cuatro palabras 'to', 'be', 'or', y 'not'.

Este ejemplo también usa el análisis integrado de cadenas proporcionado por la sentencia PARSE. En este ejemplo, el valor de WORDLIST es analizado, con la primera palabra del valor que se asigna a la variable WORD y el resto que se asigna a WORDLIST (reemplazando el valor original). [Nota del autor: puesto que la notación para variables indexadas se parece a la de las tablas (arrays, vea la próxima sección), pero no sufre las restricciones de las tablas, a mí me gusta llamarlas disarrays.]

Arrays

NetRexx también soporta los arrays (tablas) de tamaño fijo de Java. Estos son un conjunto ordenado de elementos, indexados por enteros. Para usar un array, primero debe construirlo; un elemento individual puede entonces ser seleccionado por un índice cuyo valor debe estar en el rango de 0 a N-1, donde N es el número de elementos en el array:

array=String[3] -- crear una tabla de tres Strings Java array[0]='String uno' -- asignar cada elemento del array array[1]='Otro string' array[2]='foobar' loop i=0 to 2 -- visualizarlos say array[i] end

Este ejemplo también muestra los líneas de comentario de NetRexx; la sucesión '--' (ya sea de strings literales o '/*' comentarios) indica que el resto de la cadena no es parte del programa y es un comentario.

Tracing

Definido como parte del lenguaje, el tracing de NetRexx (trazado, traceado, rastreado...) a menudo proporciona información útil sobre la depuración. El flujo de ejecución de programas puede ser rastreado, y el rastro de la ejecución puede examinado en pantalla tal como ocurre o bien capturado en un fichero. El rastro puede mostrar cada cláusula a medida que se va ejecutando, y opcionalmente mostrar los resultados de expresiones, etc. Por ejemplo, el programa:

trace results number=1/7 parse number before '.' after say after'.'before daría como resultado el rastro: 2 *=* number=1/7 >gt;v> number "0.142857143" 3 *=* parse number before '.' after >gt;v> before "0" >gt;v> after "142857143" 4 *=* say after'.'before >gt;>> "142857143.0"

donde las líneas marcadas con '*=*' son las sentencias del programa, las líneas con '>v>' muestran los resultados asignados a variables locales, y las líneas con '>>>' muestran los resultados de expresiones sin nombre.

Excepciones y manejo de errores

NetRexx no tiene una sentencia GOTO, pero se provee una sentencia SIGNAL para transferencias anormales de control, tales como cuando algo inusual ocurre. Usar SIGNAL provoca una excepción; todas las sentencias de control quedan entonces 'invalidadas' hasta que la excepción es capturada por una sentencia de control que especifica una sentencia CATCH apropiada para el manejo de la excepción. Las excepciones también se generan cuándo ocurren varios errores, tales como intenta dividir un número por cero. Por ejemplo:

say 'Por favor introduzca un número:' number=ask do say 'El inverso de' number 'is:' 1/number catch Exception say 'Lo siento, no pude dividir 1 entre "'number'"' end Aquí, la sentencia CATCH capturará cualquier excepción que surja cuando se intente la división (error de la conversión, división por cero, etc.) Cualquier sentencia de control que finalice con END (DO, LOOP, o SELECT) puede ser modificada con una o más sentencias CATCH para manejar excepciones.

Cosas que no son strings

En todos los ejemplos vistos hasta ahora, los datos que se manipulan (números, palabras, y demás) se expresan como cadenas de caracteres. Sin embargo, muchas cosas pueden ser expresadas más fácilmente de alguna otra manera, de modo que NetRexx permite a las variables referenciar a otros conjuntos de datos, conocidos como objetos.


Los objetos quedan definidos por un nombre que permite a NetRexx determinar los datos y métodos asociados al objeto. Este nombre identifica el tipo del objeto, y se denomina usualmente la clase del objeto.

Por ejemplo, un objeto de clase Oblongo podría representar un oblongo para ser manipulado y visualizado. El oblongo puede quedar definido por dos valores: su anchura y su altura. Estos valores se denominan propiedades de la clase Oblongo.

La mayoría de los métodos asociados con un objeto llevan a cabo operaciones sobre el objeto; por ejemplo podría proveerse un método 'size' para cambiar el tamaño de un objeto Oblongo. Para construir objetos se usan otros métodos (como para los arrays de NetRexx, un objeto debe ser construido antes de que pueda ser utilizado). En NetRexx y Java, estos métodos constructores siempre tienen el mismo nombre que la clase del objeto que construyen (Oblongo, en este caso).

Así es cómo se podría escribir una clase Oblongo en NetRexx (por convenio, se escribiría éste en un fichero llamado Oblongo.nrx; Java espera que el nombre del fichero coincida con el nombre de la clase que va en su interior):

/* Oblongo.nrx -- clase oblongo simple */ class Oblongo width -- tamaño (dimensión X) height -- tamaño (dimensión Y) /* Método constructor para crear un nuevo oblongo */ method Oblongo(new_width, new_height) -- cuando llegamos aquí, un nuevo objeto (no inicializado) ha sido -- creado. Copia los parámetros que hemos dado a las -- propiedades del objeto: width=new_width; height=new_height /* Cambiar el tamaño de un Oblongo */ method size(new_width, new_height) returns Oblongo width=new_width; height=new_height return this -- devolver el objeto redimensionado /* Cambiar el tamaño de un Oblongo, relativo a su tamaño actual */ method sizerelative(rel_width, rel_height) returns Oblongo width=width+rel_width; height=height+rel_height return this /* 'Imprime' lo que sabemos sobre el oblongo */ method print say 'Oblongo' width 'x' height

Para resumir: Una clase se comienza por la declaración 'class', que nombra la clase. Se sigue la declaración de la clase por una lista de las propiedades del objeto. A estos se les pueden asignar valores iniciales, si es necesario. Se siguen las propiedades por los métodos del objeto. Cada método se presenta por una declaración del método que nombra al método y describe los argumentos que deben ser suministrados al método. Se finaliza el cuerpo del método por la declaración del siguiente método (o por el fin del fichero).

El fichero Oblongo.nrx se compila como cualquier otro programa NetRexx, y debería crear un fichero de clase llamado Oblongo.class. Este es un programa para probar la clase Oblongo:

/* tryOblong.nrx -- prueba la clase Oblongo */ primero=Oblongo(5,3) -- crea un oblongo primero.print -- lo muestra primero.sizerelative(1,1) -- lo aumenta y lo imprime de nuevo segundo=Oblongo(1,2) -- crea otro oblongo segundo.print -- y lo imprime cuando se compile 'tryOblong.nrx', advertirá que el listado de referencias cruzadas de variables muestra que las variables 'primero' y 'segundo' son de tipo 'Oblongo'. Estas variables referencian a Oblongos, precisamente como las variables de ejemplos anteriores referenciaban a cadenas Rexx.

Una vez que a una variable se le ha asignado un tipo, sólo puede referenciar objetos de ese tipo. Esto ayuda a evitar errores en que una variable referencie a un objeto sin significado para ella.

--- Los programas son clases, también --- Cabe resaltar, en este momento, que todos los programas ejemplo de este documento son de hecho clases (puede haber advertido que compilándolas crea ficheros xxx.class, donde xxx es el nombre del fichero fuente). El entorno Java permitirá ejecutar una clase como una aplicación independiente solo si tiene un método constante llamado 'main' que toma un array de Strings de Java como argumento.

Si es necesario (es decir, si no hay ninguna declaración de clase) NetRexx automáticamente añade las declaraciones de clase y método necesarias, y también una declaración para convertir el array de strings (cada uno de los cuales contiene una palabra del string del comando) a un string Rexx sencillo. Por eso el ejemplo 'toast' podría haberse escrito:

/* Esto le desea la mejor salud. */

class toast

method main(argwords=String[]) constant; arg=Rexx(argwords)

Extendiendo clases

Es común, cuándo se trata de objetos, tomar una clase existente y extenderla. Una forma de hacer ésto es modificar el código fuente de la clase original -- pero éste no se encuentra siempre disponible, y con muchas personas diferentes modificando una clase, las clases podrían complicarse excesivamente con rapidez.

Los lenguajes que trabajan con objetos, como NetRexx, permiten por ello a las nuevas clases de objetos que sean configuradas a partir de las que son derivadas de clases existentes. Por ejemplo, si quería un tipo diferente de Oblongo en que el Oblongo tenía una propiedad nueva que se usaría al imprimir el Oblongo como un rectángulo, podría definirlo así:

/* charOblong.nrx -- una clase oblongo con carácter */ class charOblong extends Oblongo printchar -- el carácter a visualizar

/* Método constructor para crear un nuevo oblongo con carácter */ method charOblong(new_width, new_height, new_printchar) super(new_width, new_height) -- crea un oblongo printchar=new_printchar -- y asigna el carácter a imprimir

/* 'Imprime' el oblongo */ method print loop for this.height say printchar.copies(this.width) end

Hay varios aspectos que conviene hace notar acerca de este ejemplo: El 'extends Oblongo' en la declaración de clase quiere decir que esta clase es una extensión de la clase Oblongo. Las propiedades y métodos de la clase Oblongo son heredados por esta clase (es decir, aparecen como si fueran parte de esta clase).

Otra forma usual de decir ésto es que 'charOblong' es un subclase de 'Oblongo' (y 'Oblongo' es la superclase de 'charOblong'). Esta clase añade la propiedad 'printchar' a las propiedades ya definidas para Oblongo. El constructor para esta clase toma una anchura y altura (igual que Oblongo) y añade un tercer argumento para especificar un carácter de impresión. Primero invoca al constructor de su superclase (Oblongo) para construir un Oblongo, y finalmente asigna printchar para el objeto nuevo.

El objeto charOblong nuevo también imprime de modo diferente, como un rectángulo de caracteres, según su dimensión. El método 'print' (como tiene el mismo nombre y argumentos, -- ninguno --, que el de la superclase) reemplaza (sustituye) al método 'print' de Oblongo. Los otros métodos de Oblongo no son sustituidos, y por ello pueden ser usados en objetos charOblong.

Se compila el fichero charOblong.nrx como se hacía con Oblongo.nrx, y debería crear un fichero llamado charOblong.class. Este es un programa para probarlo:

/* trycharOblong.nrx -- prueba la clase charOblong */ primero=charOblong(5,3,'#') -- crea un oblongo primero.print -- lo muestra primero.sizerelative(1,1) -- lo aumenta y lo imprime de nuevo segundo=charOblong(1,2,'*') -- crea otro oblongo segundo.print -- y lo imprime Esto crearía los dos objetos charOblong, y los imprimiría de una manera 'carácter gráficos' simple. Observe el uso del método 'sizerelative' de Oblongo para redimensionar el objeto charOblong.

--- Argumentos optativos --- Todos los métodos en NetRexx pueden tener argumentos optativos (omitidos desde la derecha) si se desea. Para que un argumento sea optativo, debe proporcionar un valor por defecto. Por ejemplo, si el constructor de charOblong iba a tener un valor por defecto para printchar, su declaración de método podría haberse escrito:

method charOblong(new_width, new_height, new_printchar='X')

lo que indica que si no se proporciona un tercer argumento entonces se usaría 'X'. Un programa que crea un charOblong podría entonces escribirse simplemente: primero=charOblong(5,3) -- crea un oblongo lo que tendría el mismo efecto que si se hubiera especificado 'X' como tercer argumento.

Tipos binarios y conversiones

El entorno Java soporta, y en verdad requiere, la noción de tipos binarios de precisión fija 'primitiva', lo que corresponde estrechamente a las operaciones binarias usualmente disponibles a nivel hardware en los ordenadores. Brevemente, estos tipos son:

byte, short, int, y long -- enteros con signo que corresponderán a 8, 16, 32, o 64 bits respectivamente float y double -- números en punto flotante con signo que se ajustarán a 32 o 64 bits respectivamente. char -- una cantidad de 16 bits sin signo, conteniendo un carácter Unicode boolean -- un valor lógico de 1 bit, representando 'falso' o 'cierto'. Los objetos de estos tipos son manejados especialmente 'al abrigo' del entorno con el fin de lograr la máxima eficiencia; en particular, no pueden ser construídos como otros objetos -- su valor está asignado directamente. Esta distinción raramente importa al programador de NetRexx: en el caso de las cadenas literales se construye un objeto automáticamente; en el caso de un literal entero (int), no se construye un objeto.

Además, NetRexx automáticamente permite la conversión entre las diversas formas de cadenas de caracteres de Java (String, char, char[], y Rexx) y los tipos primitivos listados antes. La 'regla de oro' que sigue NetRexx es que cualquier conversión automática que se aplica no tiene que perder información: o puede determinarse en tiempo de compilación que la conversión es segura (como en int-> String) o bien se descubrirá en tiempo de ejecución si la conversión falla (como en String-> int).

Las conversiones automáticas simplifican mucho la escritura de programas para el entorno Java: raramente es necesario que el tipo exacto de los argumentos numéricos y tipo-cadena del método sea una preocupación para el programador. Para ciertas aplicaciones donde la rápida verificación o prestaciones anula otras consideraciones, NetRexx proporciona opciones para un trato diferente de los tipos primitivos:

options strictassign -- asegura coincidencia exacta de tipo para todas las asignaciones. Ninguna conversión (incluyendo las de enteros más cortos a más largos) es aplicada. Esta opción proporciona verificación de tipos más rigurosa que Java, y asegura que todos los tipos concuerdan exactamente. options binary -- usa la aritmética de precisión fija de Java sobre tipos binarios (además, los números literales, por ejemplo, se tratarán como binarios, y a las variables locales se les darán tipos 'nativos' Java tales como _int_ o _String_, donde sea posible). La aritmética binaria ofrece actualmente mejores prestaciones que la aritmética decimal de Rexx, pero pasa la carga de evitar desbordamientos y pérdida de información al programador. La declaración options (que puede registrar más de una opción) se sitúa antes de la primera declaración de clase en un fichero.

Puede también asignar explícitamente un tipo a una expresión o variable: i=int 3000000 -- 'i' es un 'int' con valor inicial 3000000 j=int 4000000 -- 'j' es un 'int' con valor inicial 4000000 k=int -- se asigna el tipo 'int' a 'k', sin valor inicial say i*j -- llevar a cabo una multiplicación y visualizar el resultado k=i*j -- llevar a cabo una multiplicación y asignar el resultado a 'k' Este ejemplo también ilustra una diferencia entre 'options nobinary' y 'options binary'. Con el anterior (el de NetRexx por defecto) el SAY visualizaría '1.20000000E+13' y se informaría de un desbordamiento de Conversión cuando se asigna la misma expresión a la variable 'k'. Con 'options binary', se usaría aritmética binaria para las multiplicaciones, y así no se detectaría ningún error; el SAY visualizaría '-138625024' y la variable 'k' toma el resultado incorrecto.

--- Los tipos binarios en la práctica --- En la práctica, la asignación explícita de tipo es necesaria en NetRexx sólo ocasionalmente. Aquellas conversiones que son necesarias para usar clases existentes (o aquellas que usan 'options binary') son generalmente automáticas. Por ejemplo, esto es un "Applet" para ser usado por navegadores con soporte Java habilitado:

/* Un sencillo Applet de gráficos */ class Rainbow extends Applet method paint(g=Graphics) -- llamado para repintar la ventana maxx=size.width-1 maxy=size.height-1 loop y=0 to maxy col=Color.getHSBColor(y/maxy, 1, 1) -- selecciona un color g.setColor(col) -- lo fija g.drawRect(0, y, maxx, y) -- y llena una tira end y

En este ejemplo, la variable 'col' será de tipo 'Color', y los tres argumentos del método 'getHSBColor' serán convertidos automáticamente a tipo 'float'. Como ningún desbordamiento es posible en este ejemplo en particular, puede añadirse 'options binary' al comienzo del programa sin que sean necesarios más cambios.

Resumen

El lenguaje NetRexx, como habrá visto, permite la escritura de programas para el entorno Java con un mínimo de sobrecarga y 'sintaxis pesada'; usar NetRexx para escribir clases Java podría incrementar su productividad en un 30% o más.

Además, al reducir la variedad de tipos numéricos y string de Java hasta una clase única que sigue las reglas de los strings de Rexx, la programación se ve en gran medida simplificada. En caso de que sea necesario, sin embargo, se dispone de acceso completo a la totalidad de los tipos y clases de Java.

Fuentes

Referencias

  • http:// www.diclib.com
  • http:// www.nasertic.es
  • http:// es.cyclopaedia.net
  • http:// www.reocities.com