64940313 lenguaje rpg
TRANSCRIPT
Lenguaje RPG
RPG es un lenguaje de programacion de IBM orientado al desarrollo de aplicaciones
empresariales, y que es muy usado en la plataforma de servidores intermedios de IBM. Ha
sido la base de los antiguos sistemas S/32, S/34, S/36, S/38, AS/400, iSeries, System i, así
como de la nueva plataforma Power 7. En el curso del tiempo ha tenido incontables mejoras
continuas hasta convertirlo en lo que es hoy, un lenguaje muy poderoso para hacer
aplicaciones de negocios.
Es un lenguaje "propietario", inventado por IBM para facilitar la programación de tareas de
negocio en las Empresas. La historia del lenguaje RPG está llena de continuas mejoras y
versiones, y la realidad ahora es que es la base (junto con Cobol) de los programas que
funcionan en muchas empresas.
En los últimos años, IBM ha mejorado en mucho RPG, ahora llamado RPG IV o RPG
ILE, dotándolo de muchas opciones y funciones (como rpg-free y %bifs), mejoras en el
compilador y creando el entorno ILE para facilitar la programación más estructurada y la
combinación de múltiples lenguajes, como Java, C++, etc.
Un ejemplo de la flexibilidad y potencia de RPG es RpgForWeb, un entorno que facilita la
creación de Aplicaciones Web usando RPG IV y el estándar de la Web; html y javascript.
Las Aplicaciones se pueden desarrollar con muchos lenguajes, incluso puede ser bueno
combinar varios lenguajes en una Aplicación, y en la mayoría de las ocasiones no importa
tanto el lenguaje con el que está desarrollada una Aplicación como el conocimiento del
medio y la inteligencia del programador.
tema del mes 68
noviembre 1996
El ILE en acción
En los AS/400 CISC, la V3R1 ha demostrado que es estable y pronto
será sustituida por la V3R2; en los AS/400 RISC, que iniciaron su
andadura con la V3R6, pronto dispondrán de la nueva V3R7: Muchos
de nosotros hemos instalado alguna de estas releases o lo haremos
muy pronto. De hecho, la consultora Gartner Group opina que a
nivel mundial, y antes de que finalice 1996, estarán en producción
(no las que se habrán vendido) más de 100.000 copias de la
V3R1/V3R2. Muchos programadores se hallan a punto de
arremangarse para ponerse a trabajar con las nuevas funciones de la
Versión 3 (Release x). Y uno de sus retos más inmediatos será el
entorno ILE de programación entender como aplicarlo con la
suficiente astucia para conseguir el máximo partido posible del nuevo modelo de programación y de lo que éste ofrece.
Si ya has jugado un poco con el ILE sabrás que no es fácil hacerse
con él a la primera y que incluso resulta fustrante aprenderlo. Dada
la abundancia de nuevos conceptos, la escasa documentación de IBM
y los escasos ejemplos, incluso un veterano programador en RPG
puede desmoralizarse. Afortunadamente, podemos separar las
funciones del lenguaje ILE (RPG IV y su nueva sintaxis) de las
características de la nueva arquitectura ILE (utilización de recursos
como grupos de activación, llamadas estáticas...). Establecer esta división nos ayudará a aprender y utilizar este entorno con eficacia.
En números anteriores de NEWS/400 ya se han tratado algunos
aspectos del ILE y del RPG IV. Así, en abril del 94, anticipándonos a
la salida de la V3, con el título de "El próximo ILE RPG IV" publicamos
una avanzadilla sobre cómo evolucionaría el RPG en el futuro. Luego
hemos publicado artículos generales como "Por fin, ILE para todos" y
"Del RPG III al ILE RPG IV y al revés..." (Marzo 95, núm. 52), o más
detallados, como "Los Grupos de Activación" (Mayo 95, núm. 54),
"Las especificaciones tipo D del RPG IV" y dos partes del artículo
sobre las "Operaciones de fecha/hora del RPG IV" (Junio y
Septiembre 95, números 55 y 56, respectivamente). A partir de este
número, además de los artículos Las funciones incorporadas y los
Subprocedimientos en RPG IV que explican otras posibilidades
añadidas al RPG, incluimos una Utilidad (CVTRPG) para convertir los
campos definidos en cálculo a las nuevas especificaciones D y diez
Trucos & Técnicas sobre el tratamiento de fechas, iniciamos una serie
que, de forma práctica, pretende familiarizar al lector en el ILE. Así,
para el próximo número tenemos previstos dos nuevos artículos, uno
sobre cómo crear programas de servicio y otro sobre las nuevas
operaciones de llamada y programación modular, dejando para el
siguiente un repaso a los Grupos de Activación, el manejo de errores en ILE o el código de operación EVAL.
Creemos que esta serie de artículos pueden ser una buena
ayuda para el aprendizaje de ILE. Tanto para aquellos que ya
habéis pasado a V3, porque podréis aprovechar su contenido
de inmediato, como para los que todavía continuáis en V2,
puesto que con ellos podréis valorar las posibilidades del ILE y
prepararos convenientemente para el futuro. Mi consejo
personal: si queréis poneros al día, no perdáis esta serie e intentad recuperar los números con lo que ya se ha publicado.
Carlos Bell
1 - Las funciones incorporadas del RPG IV
Muchos lenguajes del AS/400, incluidas las CLs, tienen funciones
incorporadas (BIF o Built-In Function) desde hace bastante
tiempo. Pero para el RPG, las funciones incorporadas son totalmente nuevas.
Podemos pensar que las BIFs son códigos de operación que
devuelven un valor sin necesidad de tener que colocar un campo de
resultado. Hasta la llegada de la V3R1, realizaba alguna de estas
funciones con códigos de operación (por ejemplo SUBST) metiendo a
presión los argumentos en el primer o en el segundo factor,
añadiendo el carácter ‘:’ para separarlos cuando era preciso. O
directamente no soportaba la función y era necesario que uno mismo se creara las sentencias para realizar el trabajo.
Con RPG IV se pueden utilizar las funciones incorporadas que son
eficientes y fáciles de entender, e incluso pueden hacer tareas que previamente requerían de ciertos trucos de programación.
Lo básico de las BIFs
IBM ha añadido las BIFs con sólo unas cuantas operaciones básicas,
pero se espera que expanda estas funciones en próximos releases. En la V3R1 el RPG IV soporta las siguientes funciones incorporadas:
%SUBST
%TRIM, %TRIML, %TRIMR
%SIZE
%ELEM
%ADDR, %PADDR
En la V3R6, además, se ha añadido la función incorporada
%PARMS.Cuando se utiliza una BIF se debe indicar los argumentos
de la función de acuerdo con el siguiente formato:
%funcion(argumento:argumento) . Los argumentos pueden ser
variables, constantes, expresiones e incluso otras funciones
incorporadas. Aunque normalmente se utilizan en los cálculos del
programa, también están soportadas por las especificaciones D utilizando valores en tiempo de compilación.
La función %SUBST
La función incorporada %SUBST (subserie) extrae una parte de una
serie de caracteres y expande las posibilidades del código de
operación SUBST. Se debe especificar la serie de caracteres, la
posición inicial desde la cual se extraerán los caracteres y la longitud, esta última es opcional.
En el ejemplo A de la figura 1 la función %SUBST coloca el valor ABC
en la variable Start, que son los primeros tres caracteres de la
constante con nombre UpperCase. La variable Middle tendrá los
caracteres LMNOP, cinco caracteres a partir de la posición 12.
Finalmente la variable End tendrá los caracteres XYX, los tres últimos
caracteres. Como en el último ejemplo no se ha especificado la
longitud de la subserie a extraer, la función %SUBST extrae todos los
caracteres hasta el final de la serie.
Si es necesario, el código de operación EVAL mueve la subserie a la
izquierda del campo de resultado, blanquea los bytes de la derecha
no rellenados por %SUBST y trunca la serie si el campo de resultado es demasiado pequeño.
Los argumentos de %SUBST también pueden ser expresiones, tal
como se ve en el ejemplo B de la figura 1. Las sentencias del ejemplo
extraen el nombre y el apellido de una serie que contiene el nombre
completo con un signo "/" como separador. Por ejemplo si el
contenido del campo LastFirst es SMITH/JOHN, las sentencias del
ejemplo extraen SMITH y lo colocan en el campo Last y hacen lo
mismo con JOHN en el campo First. Cuando se utilizan expresiones
como argumentos de las funciones incorporadas es necesario
asegurar que los argumentos y que los valores devueltos por la BIF
son correctos o el programa dará un error durante la ejecución.
Además de utilizar %SUBST para extraer una serie de caracteres,
también se puede utilizar como resultado de una asignación, o sea
para cambiar una parte de una serie de caracteres. En el ejemplo C
cambia el contenido de la variable Swine a "PigPigPigPearlsPigPig" al
especificar la función %SUBST a la izquierda del signo igual de la operación EVAL.
Probablemente es más practico utilizar %SUBST para insertar el valor
de una variable (en lugar de un literal) en una serie de caracteres, tal
como muestra el ejemplo D. En este ejemplo, la variable BarGraph
contiene el valor hexadecimal ‘20’, que las pantallas del AS/400
identifican como final de campo. La sentencia EVAL cambia el valor
de BarGraph de forma que la regla aparece por el lado izquierdo del
campo y muestra el número de caracteres indicado por la variable Percent.
Quitar caracteres en blanco con las BIFs de ajuste de blancos
Las tres funciones %TRIM x devuelven una serie de caracteres a la
que se le han recortado los blancos del comienzo y/o del final. La
función %TRIM recorta los blancos del comienzo y del final, %TRIML
sólo recorta los blancos del comienzo (izquierda) y %TRIMR sólo
recorta los blancos del final (derecha).
Las funciones %TRIM x reducen las sentencias necesarias para
concatenar campos cuando es necesario eliminar los blancos
intermedios. El RPG III necesita bastantes sentencias con
operaciones SCAN, CHECK, CHEKR y CAT para hacer lo mismo que
una sentencia EVAL de RPG IV con una o más funciones %TRIM x .
El único argumento de las funciones %TRIM x es la serie de
caracteres que será ajustada. Este argumento puede ser una variable, un literal o una constante.
El tamaño del campo
La función incorporada %SIZE da al RPG una función totalmente
nueva: devuelve el número de bytes que tiene un campo, un literal,
una estructura de datos o una constante con nombre.
Los ejemplos A y B de la figura 3 combinan las funciones %SIZE y
%TRIM para determinar si la línea a imprimir supera los 35
caracteres de longitud. Es importante destacar que en el ejemplo B el
argumento de una de las funciones incorpora otras funciones, lo que
permite eliminar sentencias y campos intermedios de trabajo.
Cuando se utiliza una serie o una tabla, o una estructura de datos de
múltiples ocurrencias como argumento de la función %SIZE, esta
devuelve el tamaño de un elemento o una ocurrencia. Para recuperar
el tamaño de toda la serie, tabla o estructura de datos de apariciones múltiples se debe incluir *ALL como segundo argumento.
Es importante recordar que la función %SIZE devuelve el número de
bytes. Cuando se utiliza para determinar el tamaño de un campo
empaquetado o binario no devuelve el número de dígitos del campo.
La función %ELEM
Esta función devuelve el número de elementos de una serie, una
tabla o el número de ocurrencias de una estructura de datos de apariciones múltiples.
Se puede utilizar esta función para que sea más sencillo mantener el
programa. Por ejemplo, en la figura 4 la serie WeeklySIs contiene las
ventas por semana y tiene 53 elementos que es el máximo número
de semanas que puede tener un año. La serie WeeklyComm, que
contiene las comisiones por semana y está definida como asociada a
la serie WeeklySIs, tiene los mismos atributos. También tiene el
mismo número de elementos que WeeklySIs, ya que la sentencia con
la palabra clave DIM utiliza la función %ELEM(WeeklySIs). Con esta
definición, si se cambia el número de elementos de WeeklySIs
también se ajustará automáticamente el número de elementos de
WeeklyComm cuando se vuelva a compilar el programa. Es necesario
recordar que las BIFs se pueden resolver durante la compilación lo
que permite utilizarlas en las especificaciones D.
Otro ejemplo que mejora la claridad del programa, y por lo tanto
hace más fácil posteriores modificaciones, se puede ver en la figura
5. La estructura de datos contiene un campo de trabajo que además
es contenido por una serie con elementos de 1 byte de longitud. La
función %ELEM coloca el número de elementos de la serie en el
campo ArrayLimit. Si la longitud del campo CustName, en el que se
basan todas las definiciones, cambia, sólo es necesario recompilar el
programa y se ajustarán todos los valores y tamaños de las variables que dependen de él.
También se puede utilizar la función %ELEM en los cálculos, tal como
se muestra en el ejemplo B. En este ejemplo se limita el número de
veces que se ejecuta el DOU con el número de elementos de la serie
WeeklySIS. De esta forma, no es necesario modificar ninguna
sentencia si cambia el número de elementos de la serie. Además,
como regalo, si se escribe de esta forma la sentencia DOU, queda
documentado el motivo del bucle: para procesar cada elemento de la serie.
Apuntando a %ADDR y %PADDR
Las funciones %ADDR (Dirección) y %PADDR (Dirección de
Procedimiento) son dos formas de dar soporte de punteros al RPG.
Aunque trataremos más ampliamente el tema de punteros en
próximos números, en este artículo daremos una visión rápida para estas dos BIFs.
Los punteros son variables que contienen las direcciones de otras
variables (o procedimientos) de un programa en lugar de contener el
valor de las variables. La función %ADDR coloca la dirección de una
variable, un elemento de una serie o una expresión en un puntero. El
resultado es una variable (del nuevo tipo de datos puntero) con la
dirección de la variable especificada.
En A en la figura 6 se ha definido DayPtr con el tipo de datos *, lo
que indica que el campo es un puntero. Se ha utilizado la palabra
clave INZ junto con la palabra clave %ADDR para inicializar este
puntero con la dirección de la serie DayOfWeeks. Se puede cambiar
el valor de la dirección del puntero asignándole un nuevo valor en las
sentencias de cálculo, tal como se puede ver en el ejemplo B. En este
caso se ha incluido la función %ADDR en una sentencia EVAL para
asignarle a DayPtr la dirección del cuarto elemento de la serie DaysOfWeek.
La función %PADDR devuelve la dirección del punto de entrada de un
procedimiento (programa). La variable que recibe la dirección debe
ser del tipo de datos puntero. Se pueden utilizar los punteros de
procedimientos con el código de operación CALLB (Llamar a un
procedimiento enlazado) para enlazar estáticamente una llamada a un procedimiento.
En el ejemplo C de la figura 6 se define un puntero de procedimiento
(tipo de datos *) con la palabra clave PROCPTR. Luego se inicializa el
puntero con la dirección del procedimiento ADDCUST utilizando la
función %PADDR en la palabra clave INZ. Después, en las
especificaciones de cálculo, se llama al procedimiento ADDCUST
mediante la operación CALLB. Normalmente, se ejecuta más
rápidamente la llamada a un procedimiento por su dirección que si se utiliza un literal o una constante con nombre en el segundo factor.
La función incorporada más reciente
En la V3R6 se ha incorporado la función %PARMS. Esta BIF devuelve
el número de parámetros que se han pasado al procedimiento donde
se está utilizando la función %PARMS. Para el procedimiento principal
la función %PARMS es equivalente a la palabra especial *PARMS de
la estructura de datos del programa. Puede obtener más información
sobre procedimientos, procedimiento principal y subprocedimientos
en el artículo "Subprocedimientos en RPG IV" en este mismo número.
Si el número de parámetros es desconocido el valor devuelto es -1. El
valor devuelto por %PARMS no está disponible si al programa o
procedimiento que llama al procedimiento que ejecuta la función
%PARMS no envía un mínimo de información de la descripción
operacional. El ILE RPG/400 siempre pasa esta descripción
operacional pero otros lenguajes no pasan ninguna.
¿Algo más sobre las BIFs?
Ahora que conoce las funciones incorporadas puede comenzar a
utilizar estas nueve BIFs que IBM ha incorporado en el RPG. Puede
mirar otros lenguajes como C, CLs o Basic para ver algunas de las
posibilidades que las funciones incorporadas al ILE RPG IV ofrecen al programador.
Examine sus aplicaciones e intente ver dónde puede utilizar las BIFs
(conjuntamente con las demás novedades del RPG IV) para conseguir
que sus programas RPG sean más fáciles de mantener, más fiables, más entendibles, más eficiente y, en general, mejores.
Bryan Meyers, es director de los servicios de información de KOA y miembro del equipo de redactores técnicos internacionales de NEWS/400.
2 - Subprocedimientos en RPG IV
La introducción e implementación del RPG IV ha tenido muchas
controversias, compromisos y concesiones. A pesar de que la nueva
sintaxis del lenguaje añade muchas funciones, en la primera release
no se encontraban algunas de las más esperadas. En la parte
superior de esa hipotética lista se encontraba poder pasar
parámetros a las subrutinas. Y un poco después, la posibilidad de
definir variables locales en una subrutina, de forma que cambiar
alguna de ellas no afectara al resto del programa. Después de un año
y pico de la presentación del RPG IV, IBM ha empezado a atender
esta lista de deseos y está añadiendo nuevas funciones. Para
comenzar, ha añadido los subprocedimiento y las variables locales,
que probablemente sean dos de las funciones más
deseadas/necesarias.
La finalidad de los subprocedimientos es muy similar a la de las
subrutinas, pero existen diferencias. Las mayores diferencias entre
ambas son las siguientes:
• Se pueden pasar parámetros a los subprocedimientos.
• Con subprocedimientos se pueden definir datos y variables locales.
• Los subprocedimientos pueden devolver un valor.
• Los subprocedimientos se pueden utilizar directamente en expresiones.
Los subprocedimientos ayudan a crear código fuente modular y crear
"funciones incorporadas" (built-in-functions, BIF) propias para las
aplicaciones RPG. Oficialmente los subprocedimientos son una mejora
añadida al RPG IV en la V3R6, pero también estarán disponibles en la
V3R2 para los modelos CISC, por lo tanto no es necesario que se compre un nuevo AS/400 RISC para poder utilizarlos.
Procedimientos dentro de un procedimiento
Hasta ahora, los programas RPG eran programas con un sólo
procedimiento, con un sólo punto de entrada al programa. Esto
significa que solamente se podía llamar a "todo" el programa, pero no
se podía ejecutar una sola subrutina del programa. Con el nuevo
soporte de subprocedimientos, se pueden escribir programas RPG
que tengan un procedimiento principal y, opcionalmente, que tengan
uno o más subprocedimientos. A éstos se les pueden pasar
parámetros y pueden tener sus propias variables locales que no
interfieren con el resto de variables del programa. Se pueden incluir
todas las sentencias del procedimiento principal y de cada uno de los
subprocedimientos en el mismo miembro fuente o se puede tener el
código correspondiente a los subprocedimientos en otro, u otros, miembros fuentes que se compilará, o compilarán, por separado.
Desde el procedimiento principal se pueden llamar a los
subprocedimientos utilizando una sintaxis similar a la utilizada para
ejecutar las funciones incorporadas (BIF) del RPG IV. Por ejemplo
para llamar al subprocedimiento DayOfWeek puede escribir la siguiente sentencia:
EVAL WeekDay = DayOfWeek(TodaysDate)
O puede utilizar el subprocedimiento en una sentencia IF:
IF DayOfWeek(TodaysDate) > 1
Normalmente, un subprocedimiento devuelve un valor al
procedimiento principal. En el ejemplo anterior, el valor devuelto será
el número que le corresponde al día de la semana. Una función de un
subprocedimiento, sin embargo, puede actualizar una variable global
o posicionar el puntero de un archivo.Para poder entender mejor los
subprocedimientos y en qué casos se pueden utilizar, veamos un
ejemplo que convierte una subrutina RPG IV en un subprocedimiento.
La metamorfosis
Nuestra subrutina ejemplo convierte una fecha en el día de la
semana correspondiente. La figura 1 muestra esta subrutina dentro
de una parte de un programa RPG IV y se ha seleccionado de un
ejemplo del artículo "Trucos de fechas en RPG IV", publicado en
este mismo número. Para ejecutarla sólo es necesario escribir una
sentencia con el código de operación EXSR y el nombre de la
subrutina. La figura 2 muestra la misma subrutina escrita como un
subprocedimiento que devuelve un valor numérico que representa el
día de la semana (1=Domingo, 2=Lunes, etc.). Para ejecutar este
subprocedimiento debe utilizarse el mismo tipo de llamada que se
utiliza con las nuevas BIF (funciones incorporadas o built-in-
functions). A primera vista, las sentencias de la figura 2 parecen ser
las de un programa normal en RPG IV, sin embargo, cuando se mira
con profundidad aparecen las diferencias entre la subrutina y el
subprocedimiento. Para empezar, aparece la nueva especificación
tipo "P" (de procedimiento) que define el comienzo y el final del
subprocedimiento. La especificación P contiene sólo el nombre del
procedimiento y una letra B si se está definiendo el inicio del
procedimiento o una E si se define el final. Digamos que la sentencia
que contiene la B es equivalente al código de operación BEGSR en la subrutina y la que contiene la E es equivalente a ENDSR.
Después de la especificación P se define la interfase de
procedimiento (PI), que es similar a la lista de parámetros *ENTRY.
Para definir el PI se utilizan las especificaciones D y se debe indicar PI
como tipo de estructura en las columnas 24 y 25. En la misma línea
también se puede definir la longitud, el tipo de datos y las posiciones
decimales del valor que será devuelto, en este ejemplo el campo es
de un dígito empaquetado con cero posiciones decimales. Los campos
siguientes definen los parámetros que son pasados al procedimiento, en el ejemplo de la figura 2 el campo pasado es DateIn.
A continuación se colocan las especificaciones D que definen las
variables locales que necesita el subprocedimiento. Como estas
variables son definidas dentro de los limites del subprocedimiento,
son variables locales especificas para él. Si otro procedimiento en el
programa (incluido el procedimiento principal) define un campo con el
mismo nombre, por ejemplo el campo DayNbr, ambos campos
representarán variables distintas. El sistema no conserva los valores
de las variables locales en las distintas llamadas a un procedimiento.
Si esto ocurre varias veces, los valores de las variables locales de una
llamada anterior, no se conservan en la siguiente llamada.
Las sentencias C de la figura 2 son concisas. Es importante señalar
que se ha incluido el código de operación RETURN con una nueva
función. No solamente es una forma de finalizar el subprocedimiento
sino que también indica el nombre de la variable cuyo valor será
devuelto al programa que ha llamado al subprocedimiento. En este caso, se devuelve el valor de DayNbr.
El código de operación RETURN puede devolver el valor de una
variable (como en la figura 2) y también el resultado de una
expresión de formato libre (como por ejemplo, DayNbr + 2). Un
subprocedimiento puede tener más de un código de operación
RETURN, pero sólo se puede devolver un valor. Por lo tanto, las sentencias de la figura 2 se pueden escribir de la siguiente forma:
IF DayNbr < 1
RETURN DayNbr + 7
ELSE
RETURN DayNbr
ENDIF
Cuando se ejecuta una operación RETURN el subprocedimiento
finaliza, tanto si devuelve el valor de una variable como si devuelve el resultado de un cálculo.
Esto es prototípico
Antes de que pueda utilizar un subprocedimiento en un programa hay
un concepto más que debe entender: la definición prototipo . Una
definición prototipo es una lista de los parámetros de los
subprocedimientos en orden, describiendo el tipo de datos del valor
devuelto y el tipo de datos de los parámetros que se envían. Los
prototipos suministran una verificación de seguridad entre
procedimientos y subprocedimientos, permitiendo que el compilador
compruebe si la llamada al subprocedimiento es correcta. Sin la
definición prototipo podrían crearse misteriosos errores de programas
causados por pasar datos inválidos a un subprocedimiento o asumiendo tipos de datos devueltos incorrectamente.
Los prototipos aparecen, normalmente, en el procedimiento principal
de un programa que utiliza subprocedimientos. Cada procedimiento
utilizado por un programa tiene su propia definición prototipo que
tiene, usualmente, el mismo formato que el PI. La figura 3 muestra
la definición prototipo para el subprocedimiento DayofWeek del
ejemplo. Se puede ver que el tipo de estructura, en las columnas 24
y 25, es PR y aparece junto con el nombre del subprocedimiento en
la primera línea de la definición prototipo. La definición de la figura 3
también indica que cada vez que el programa llame al
subprocedimiento DayofWeek, el programa debe pasar una variable
de fecha y debe esperar que la devolución de un número empaquetado de 1 byte.
A pesar de que es una practica habitual en muchos lenguajes utilizar
el mismo nombre de variable que utiliza el subprocedimiento, no es
algo obligatorio. Los nombres de variables aparecen en la lista de
parámetros del prototipo pero se puede utilizar cualquier nombre de variable e incluso no utilizar ninguno.
Normalmente se copia la definición prototipo en el programa que
utiliza el subprocedimiento. De hecho se pueden agrupar todas las
definiciones prototipo de todos los subprocedimientos en un miembro
fuente y luego copiar el miembro en los programas. El compilador
pasa por alto los prototipos no referenciados en el código. Para no
tener que escribirlas varias veces en distintos programas, y evitar los
posibles errores, se puede utilizar /COPY para copiar las diferentes definiciones prototipo.
Además de copiar el prototipo en los programas que llaman a los
subprocedimientos, debería incluir el prototipo en el fuente que
contiene los subprocedimientos. Esto permite al compilador asegurar
que el prototipo que utilizará en sus programas coincide con el
subprocedimiento que está definiendo. Cuando se compila el
subprocedimiento, el compilador indicará cualquier diferencia en las longitudes y los tipos de datos.
Se puede utilizar esta capacidad de los prototipos para asegurar que
son correctos la cantidad y tipo de parámetros pasados cuando se
utiliza RPG para llamar un programa o un subprocedimiento hecho en
cualquier lenguaje ILE, esto incluye todas las APIs para ILE (con la
condición de que el RPG soporte los mismo tipos de datos que utiliza
la API). Si se utiliza un prototipo para definir los parámetros, se
puede llamar al programa (o a la API) con la misma sintaxis que se utiliza para ejecutar las funciones incorporadas.
También se pueden utilizar los prototipos con el nuevo código de
operación CALLP (Llamar subprocedimiento), en lugar de utilizar el
subprocedimiento en una sentencia EVAL o IF, para llamar a
subprocedimientos o subprogramas que no devuelven un valor. La
operación CALLP permite especificar los parámetros en formato libre y tiene la siguiente sintaxis:
CALLP Prototype(Parm1:Parm2: ... :ParmN)
La última palabra en subprocedimientos
Probablemente ya estará pensando en las diferentes formas de
incorporar subprocedimientos en sus programas. Puede utilizarlos
para crear su propio conjunto de herramientas y luego las podrá
incluir en sus aplicaciones fácilmente, sin tener que preocuparse de
posibles conflictos con los nombres de campo o con los indicadores. Y
por supuesto, también puede utilizarlos para crear funciones que se salgan del estándar suministrado por IBM en el RPG.
Los subprocedimientos pueden crear una industria totalmente nueva
en el mundo del RPG: podrán suministrar juegos de herramientas
especializados para que aquellas instalaciones de AS/400 con pocos
medios técnicos, puedan armar en aplicaciones completas. Aunque
esta industria nunca pueda competir con el mercado de custom
controls VBX del Visual Basic, los componentes pueden ser un buen
negocio para muchos suministradores de software y cambiar la forma en que se compran las aplicaciones para el AS/400.
Bryan Meyers , es director de los servicios de información de KOA y miembro del equipo de redactores técnicos internacionales de NEWS/400. Jon Paris, con más de 20 años de experiencia en proceso de datos, actualmente es asesor de desarrollos en los Laboratorios de IBM Toronto.
© Publicaciones HELP400, S.L. (Todos los derechos reservados)
help400.es
Información técnica y de gestión para IBM i
- AS/400
Acceda al Sumario de
cualquier número
Número (y pulse INTRO)
Actualizado el 31 Julio 2011
1024 x 768
de resolución
MENU de OPCIONES
RPG IV %BIFs
funciones incorporadas en Lenguaje IBM RPG IV
información provisional
RPG es un Lenguaje de Programación de IBM, principalmente usado en su plataforma intermedia, y con una historia de 40 años, en los cuales ha tenido incontables mejoras sucesivas hasta alcanzar hoy dia la version RPG IV (tambien llamado ILE), que incluye un formato de escritura libre denominado rpg-free y contando con un montón de funciones incorporadas denominadas %bif.
En la página RPG hay algunos enlaces interesantes de IBM
Los %bif son funciones incorporadas dentro del lenguaje para hacerlo más poderoso. Por ejemplo:
Alfa = %trim(PgmName); la funcion %trim elimina los blancos
Alfa = %edit(Saldo:'J'); edita el campo Saldo con el codigo de edicion J
Alfa = %trim(%edit(Saldo:'J')); ya que al editar un campo quizá queden espacios en blanco, la %trim anidada los quita
Hay un montón de funciones %bif, creciendo con cada versión del Operativo y del Lenguaje...
%mseconds, %seconds, %minutes, %hours, %days, %months y %years
%DIFF, para restar un valor de fecha, hora o indicación de la hora de otro
Funciones para convertir una serie de caracteres (o fecha o indicación de la hora) en una fecha, hora o indicación de la hora: %DATE, %TIME y %TIMESTAMP.
La función %SUBDT, para extraer un subconjunto de una fecha, hora o indicación de la hora
– Funciones para asignar o reasignar almacenamiento: %ALLOC y %REALLOC.
– Funciones para buscar un elemento en una matriz: %LOOKUP, %LOOKUPGT, %LOOKUPGE, %LOOKUPLT y %LOOKUPLE.
– Funciones para buscar un elemento en una tabla: %TLOOKUP, %TLOOKUPGT, %TLOOKUPGE, %TLOOKUPLT y %TLOOKUPLE.
– Funciones para verificar que una serie contenga sólo los caracteres especificados (o buscar la primera o última excepción a esta norma): %CHECK y %CHECKR
– La función %XLATE, para convertir una serie a partir de una lista de caracteres origen en caracteres destino.
– La función %OCCUR, para obtener o establecer la aparición actual de una estructura de datos de apariciones múltiples.
– La función %SHTDN, para determinar si el operador ha solicitado la conclusión.
– La función %SQRT, para calcular la raíz cuadrada de un número.
%SCAN
La función incorporada %PADDR ahora puede tomar un nombre de prototipo o un nombre de punto de entrada como argumento
Direct conversion of date/time/timestamp to numeric, using %DEC:
%DEC is enhanced (v5r3) to allow the first parameter to be a date, time or timestamp, and the optional second parameter to specify the format of the resulting numeric value.
Example:
D numDdMmYy s 6p 0
D date s d datfmt(*jul)
date = D'2003-08-21';
numDdMmYy = %dec(date : *dmy);
// now numDdMmYy = 210803
Conversion from character to numeric
Built-in functions %DEC, %DECH, %INT, %INTH, %UNS, %UNSH and %FLOAT are enhanced to allow character parameters. For example, %DEC('-12345.67' : 7 : 2) returns the numeric value -12345.67.
---
New assignment operators
The new assignment operators +=, -=, *=, /=, **= allow a variable to be modified based on its old value in a more concise manner.
Example: totals(current_customer) += count;
This statement adds "count" to the value currently in "totals(current_customer)" without having to code "totals(current_customer)" twice
----
%KDS(data structure) Used in free-form keyed operation codes CHAIN, SETLL, SETGT, READE and READPE, to indicate that the keys for the operation are in the data structure.
Functions for verifying that a string contains only specified characters (or finding the first or last exception to this rule): %CHECK and %CHECKR
The %XLATE function, for translating a string based on a list of from-characters and to-characters.
The %OCCUR function, for getting or setting the current occurrence in a multiple-occurrence data structure.
The %SHTDN function, for determining if the operator has requested shutdown
%XFOOT built-in function sums all elements of a specified array expression
EVALR operation code evaluates expressions and assigns the result to a fixed-length character or graphic result. The assignment right-adjusts the data within the result.
The new FOR operation code performs an iterative loop and allows free-form expressions for the initial, increment, and limit values.
The new LEAVESR operation code can be used to exit from any point within a subroutine.
The new *NEXT parameter on the OVERLAY(name:*NEXT) keyword indicates that a subfield overlays another subfield at the next available position.
The new *START and *END values for the SETLL operation code position to the beginning or end of the file.
Built-in functions %EOF, %EQUAL, %FOUND, and %OPEN have been added to query the results of input/output operations. Built-in functions %ERROR and
%STATUS, and the operation code extender 'E' have been added for error handling.
Built-in functions %CHAR and %REPLACE have been added to make string manipulation easier
New support for externally defined *CMDY, *CDMY, and *LONGJUL date data formats
Built-in functions %CHAR(graphic, date, time or timestamp expression) Returns the value in a character data type.
%EOF{file name} Returns '1' if the most recent file input operation or write to a subfile (for a particular file, if specified) ended in an end-of-file or beginning-of-file condition; otherwise, it returns '0'.
%EQUAL{file name} Returns '1' if the most recent SETLL (for a particular file, if specified) or LOOKUP operation found an exact match; otherwise, it returns '0'.
%ERROR Returns '1' if the most recent operation code with extender 'E' specified resulted in an error; otherwise, it returns '0'.
%FOUND{file name} Returns '1' if the most recent relevant operation (for a particular file, if specified) found a record (CHAIN, DELETE, SETGT, SETLL), an element (LOOKUP), or a match (CHECK, CHECKR and SCAN); otherwise, it returns '0'.
%OPEN(file name) Returns '1' if the specified file is open and '0' if the specified file is closed.
%REPLACE(replacement string: source string {:start position {:source length to replace}}) Returns the string produced by inserting a replacement string into a source string, starting at the start position and replacing the specified number of characters.
%STATUS{file name} If no program or file error occurred since the most recent operation code with extender 'E' specified, it returns 0. If an error occurred, it returns the most recent value set for any program or file status. If a file is specified, the value returned is the most recent status for that file.
Operation code Extender E Allows for error handling using the %ERROR and %STATUS built-in functions on the CALLP operation and all operations that allow error indicators.
New century formats *CMDY (cmm/dd/yy) To be used by the MOVE, MOVEL, and TEST operations.
*CDMY (cdd/mm/yy) To be used by the MOVE, MOVEL, and TEST operations.
New 4-digit year format *LONGJUL (yyyy/ddd) To be used by the MOVE, MOVEL, and TEST operations.
editing (%EDITW, %EDITC, %EDITFLT)
scanning strings (%SCAN)
type conversions (%INT, %FLOAT, %DEC, %UNS)
type conversions with half-adjust (%INTH, %DECH, %UNSH)
precision of intermediate results for decimal expressions (%DEC)
length and decimals of variables and expressions (%LEN, %DECPOS)
absolute value (%ABS)
set and test null-capable fields (%NULLIND)
handle null terminated strings (%STR)