Alters

Remote Tools: Teoría de programación (I) - Arreglos en COBOL

Buenas!

Se acaban mis vacaciones, pero quedo con la buena sensación de haber descansado y poner ciertas cosas en su sitio...

Los dos próximos meses serán un no parar, así que es posible que esté más ausente que nunca (sobretodo en julio). Es posible que algunos meses también esté "a half" por temas personales.

Pero bueno, uno hace lo que puede, ¿no? y mientras encuentre una hora libre al día podré dedicarme a escribir y plasmar mis conocimientos, que es a lo que venimos aquí :-)

Y bien, en esta entrada nos metemos en la segunda parte de Remote Tools, la herramienta para smartphone que iré desarrollando como método de aprendizaje y como entretenimiento...

Esta parte, al igual que el segundo tema de matemáticas, constará de cinco partes. Vamos a ver el índice y cómo lo estructuraremos.





  1. Teoría de programación
    1. COBOL
      1.  Teoría
        1. Array
        2. Fichero dinámico
    2. .NET
      1. Teoría
        1. Procesos
        2. Repaso FTP
    3. nmap
      1. ¿Qué es?
      2. ¿Para qué sirve?
      3. Teoría
        1. Línea de comandos
        2. Comunicación
El temario que veremos está estructurado por colores.

Por tanto, en esta entrada veremos los "array" con COBOL.

Si (en su día) seguisteis el mini-curso de COBOL que dejé por aquí, recordaréis que las variables en COBOL son  un concepto completamente diferente al que mucha gente está acostumbrado (se parece, quizás, a un campo formateado de una base de datos, o a las variables de SAP - ya que, en mi opinión, el 80% de código de SAP puede ser leído como COBOL...)

Si llegado este punto no os acordáis, os dejo aquí el link al mini-curso de COBOL.

Bueno, sigamos...

En COBOL hay dos maneras de definir un arreglo: con la cláusula REDEFINES y con la cláusula OCCURS

¿En qué se diferencian?

Pues, usando un poco el inglés (ya que COBOL se auto-ducmenta), la primera redefine un campo, mientras que la segunda hace que se repita.

Quizás la cosa no ha quedado del todo clara, ya que puede parecer todo un poco ambiguo. Veamos un par de ejemplos:

Ejemplo para REDEFINES:

01  LETRAS.
        02 LETRAS PIC X(27) VALUE "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ".
        02 LETRAS-SUELTAS REDEFINES LETRAS OCCURS 27 PIC X.

Fijémonos qué está pasando aquí:

Creamos una estructura "LETRAS" (nivel 01). Dentro de esta estructura tenemos "LETRAS" con un pattern de X(27) (27 caracteres alfanuméricos).

Finalmente, creamos otra variable llamada "LETRAS-SUELTAS", con cláusula REDEFINES, y le decimos que "OCCURS 27 PIC X" (se repite 27 veces con PIC X).

Es decir, en JAVA estaríamos haciendo algo así (para que se vea gráficamente):

String letras"ABCDEFGHIJKLMNÑOPQRSTUVWXYZ";
String[] letras-sueltas;

for(int i=0;i<27;i++)
  letras-sueltas[i] = letras.charAt(i);

En COBOL, podríamos modificar el REDEFINES, y poner, por ejemplo:

01 TIEMPO.
    02 FECHA PIC 9(6).
    02 CAMPOS REDEFINES FECHA OCCURS 3 PIC 99.

De esta manera, en "CAMPOS" tendríamos la fecha en formato DD-MM-YY.

Aquí, a la vez, hemos visto un uso de OCCURS. Y es que se usa de manera similar a la que hemos visto ahora.

Vamos a explicar un poco mejor para qué sirve la cláusula OCCURS cuando la usamos en solitario:

01 ABECEDARIO.
    02 LETRA OCCURS 27 TIMES.
       03 L PIC X.

Ahora, estamos creando (por así decirlo) una tabla llamada "ABECEDARIO", con un único campo llamado "LETRA", que se repite 27 veces, y cuyo pattern es PIC X.

No vemos mucha diferencia, ¿no?

Vamos a extraer (literalmente) un fragmento del manual de COBOL que consulto cuando tengo alguna duda en COBOL (aquí): 

01 TABLA.
   02 TRABAJADORES OCCURS 100 TIMES.
        03 NOMBRE PIC X(30).
        03 NIF PIC X(10).
        03 SALARIO OCCURS 12 TIMES.
            05 BRUTO PIC S9(8).
            05 NETO PIC S9(8).
            05 GASTOS OCCURS 10 TIMES.
                07 GASTO PIC S9(8).

Ahora creo que se verá mejor la diferencia entre un REDEFINES y un OCCURS.

Veamos con calma qué está pasando arriba:

Tenemos que ver la variable (como su nombre indica) como una tabla; más bien como un conjunto de tablas.

La TABLA tiene un único campo, TRABAJADORES, que se repite 100 veces (como máximo podremos guardar 100 trabajadores).

Cada trabajador tiene, a su vez un NOMBRE, NIF y SALARIO.

El SALARIO aparece 12 veces (uno para cada mes del año), y tiene tres campos: BRUTO, NETO y GASTOS.

Los GASTOS pueden darse 10 veces cada mes (120 entradas de GASTO por TRABAJADOR y año).

Si fuera una relación de tablas en una base de datos, podríamos hacer el siguiente esquema:






























Tendríamos algo como esto, pero esquematizado y compactado en una sola variable.

Para algunos es una ventaja, para otros un inconveniente... sea como sea, la cláusula OCCURS es una flagrante demostración del poderío que puede desatar COBOL cuando se usa con razón.

Y bien, dejando un poco de lado el cómo definir arreglos en COBOL, vamos a ver cómo acceder a ellos.

Se hace como en cualquier otro lenguaje: especificando el índice al que accedemos. Un ejemplo basado en REDEFINES (por ser más simple), sería:

* Tenemos nuestra estructura LETRAS definida
77 CONT PIC 99 VALUE ZERO.

PROCEDURE DIVISION.
    INICIO.
        PERFORM MUESTRA VARYING CONT FROM 1 BY 1 UNTIL CONT > 28.

    MUESTRA.
        DISPLAY LETRAS-SUELTAS(CONT).

Y, ¡voliá! recorremos nuestro arreglo en COBOL.

Hay que tener en cuenta una cosa: el índice empieza en 1 (no en 0). Si os fijáis primero declaro CONT con PIC 99 VALUE ZERO, pero en el bucle PERFORM le digo que empieze en 1 (FROM 1).

Es muy importante tener esto en cuenta para prevenir errores en tiempo de ejecución (sería un ArrayIndexOutOfBounds, en JAVA).

Para tablas y demás, tendremos que tratar la variable como una matriz compleja. En el caso de querer saber los datos del TRABAJADOR número 15, haríamos:
  • Nombre: NOMBRE(15)
  • NIF: NIF(15)
  • BRUTO (del mes "M"): BRUTO(15, M)
  • NETO (del mes "N"): NETO(15, N)
  • GASTO(del mes "M", gasto número "G"): GASTO(15, M, G)
Espero que os sea útil esta entrada... la próxima veremos cómo usar ficheros de manera dinámica (todo un avance).

Como siempre, ¡Hasta la próxima!