Se me viene a la
memoria una frase que se atribuye a Bill Gates: “No sé
qué lenguajes de programación existirán en el futuro. Lo que sí sé es que COBOL
estará en la lista”.
Nunca se ha distinguido por la calidad de sus
productos, pero sí por la visión.
0. INTRODUCCIÓN
0.1. AGRADECIMIENTO
Has oído hablar del
lenguaje de programación COBOL. Tal vez por eso te has acercado a leer estas
líneas. Gracias por anticipado. Espero sinceramente que lo disfrutes y que lo
aproveches al máximo.
0.2.
PROFECÍAS (NO) AUTOCUMPLIDAS
Dicen que COBOL es
vetusto, está obsoleto y es poco amable. Pero ahí sigue, en el corazón de los
grandes sistemas que manejan los mayores negocios del mundo. Desde que tengo
uso de razón -y peino ya algunas canas- escucho profecías sobre el final del
COBOL. Pasa el tiempo y siguen sin cumplirse.
0.3.
(PRE)HISTORIA
La historia de los
primeros ordenadores está en la red, lo que hace innecesario -y cansino-
ponerse a repetirla. Busca en la wikipedia a Grace Murray Hoppery lo demás aparecerá casi solo.
Observa que acabo de hacer una mención especial a esta gran señora (la madre
amantísima de todos los COBOLeros) por su gran aportación a la informática
empresarial. Y porque el libro lo escribo yo. Faltaría más.
0.4.
MOTIVACIÓN
Programar en COBOL
otorga acceso a puestos mejor remunerados que la media y proporciona un “halo
de encanto” especial a quienes dominan este lenguaje. En la red
encontrarás una multitud de referencias a la frase “Los hombres de verdad
programan en COBOL” con sus imágenes y todo.
0.5.
CARENCIAS
Para programar en
COBOL con eficiencia tendrás que resignarte a relegar tu “entorno gráfico” a un
discreto segundo plano. Todas las cosas interesantes ocurrirán en una sola
ventana en “modo de texto” que -deliberadamente- usa una tipografía de paso
fijo y no sabe nada de imágenes o vídeos. Sin embargo, podrás aprovechar
las capacidades de los entornos modernos para trabajar. Copiar y pegar código
COBOL es igual que manejar texto en el portapapeles. Un editor de texto “plano”
y una ventana de “comandos” harán maravillas con el programa.
La lógica de los programas resultará
“lineal” en mucha medida. Empezarán por el principio y terminarán por el final,
siguiendo un argumento que no se verá perturbado por eventos externos, tal y
como ocurre normalmente en los entornos gráficos.
Esto, a los que ya somos algo
mayorcitos, nos llena de paz. Porque NO, no nos gustan las malditas ventanas.
Este texto no va a llevarte al punto
(de tu camino como programador) en el que ya puedes enfrentarte a proyectos
serios. Me conformo con dejarte justamente al principio de ese camino. Eso sí, estarás
bien preparado para entender lo que te espera. Siempre y cuando tu
objetivo sea la programación profesional en la zona “vintage” del departamento
de desarrollo informático de un gran banco.
Para hacer cosas “modernas” existen
otros lenguajes y herramientas. Aquí valoraremos el discreto encanto de la
simplicidad, la elegancia de lo que no pasa de moda, la sobriedad de la
decoración minimalista.
Si no estás dispuesto a disfrutar en
estos términos, más vale que no pierdas el tiempo. Con toda seguridad, ya
tienes edad para decidir si sigues leyendo o cambias de lectura. Existen
unos preciosos libros de Java. Con sus gráficos, sus colores y sus
nombres de funciones y variables que no caben en la página y están salpicados
de letras mayúsculas y minúsculas. Para más INRI, esas malditas
capitalizaciones son significativas.
0.6.
PARADIGMA
Para ponerlo fácil,
intentaremos tropezar lo menos posible con las complicaciones propias de los
grandes entornos IBM. Sin embargo, tiene que empezar a sonar algún que otro
concepto y algún que otro barbarismo anglosajón acuñado en los gloriosos
tiempos del francés como segunda lengua extranjera.
Hubo un tiempo en el que -se suponía
que- la lengua gala protagonizaría la vida diplomática, y por eso se consideró
interesante su aprendizaje. No seamos demasiado crueles con quienes
confeccionaron los planes de estudios de nuestra infancia. Seguramente jamás
viajaron más allá de Arenas de San Pedro. Por cierto, hermoso lugar.
Vamos en busca de esos conceptos
fundamentales. Despacito, para no atragantarnos.
0.7. LA PICADORA
Si eres de pueblo
te resultará familiar el tiempo de la matanza. Mucho frío, mucha gente, olores
y sabores peculiares, cerdos que chillan, comida y bebida.
En caso contrario, un poco de
imaginación bastará. Hasta para ti, adicto o adicta a la ciudad, es evidente
que los chorizos y los salchichones no crecen en los árboles.
Una máquina de picar carne nos ayuda
a convertir los pedazos del animal en exquisitos embutidos. La abstracción de
esta máquina al mundo informático servirá para ilustrar el funcionamiento de un
programa básico.
0.8. ENTRADA, PROCESO Y SALIDA
Las tres partes fundamentales del
asunto, cuando de programas básicos se trata.
Entrada: La carne llega a la máquina
en un recipiente, previamente condimentada y cortada en trozos del tamaño
adecuado.
Proceso: Una vez en el interior se
realiza el picado de la carne.
Salida: La carne picada sale de la
máquina y cae en un envoltorio (que antiguamente era una tripa de animal) para
contenerla, protegerla y darle la forma adecuada. Posteriormente se realiza el
curado, secado y envasado.
Entrada de datos, proceso de datos y
salida de datos. Sencillo, elegante, natural y respetuoso con el medio
ambiente.
¿Lo recordarás? Seguro. Pero pronto
llegarás a la conclusión de que estas tres partes son en realidad cinco:
Preproceso, Entrada, Proceso, Salida y Postproceso. Al tiempo.
Quiero creer que a mí también me
recordarás cuando veas escritos (en clave) símbolos parecidos a “I/O”, o sus
equivalentes directos en español “E/S”. Se refieren a las operaciones que el
sistema realiza para obtener los datos necesarios “de entrada” y para entregar
los que ya se procesaron, los “de salida”.
En el lenguaje de bajo nivel de las
máquinas IBM existía una llamada de bajo nivel (SVC, o “supervisor call”)
denominada SIO (acrónimo anglosajón de “start input/output”) para obtener o
entregar información “contenida en” o “destinada a” medios de almacenamiento
externos.
0.9. DATOS, DATOS, DATOS
El lector atento ya ha intuido que el
objeto de las lecturas de información (la “entrada” de las páginas anteriores)
es llevar los datos a la memoria del programa, donde su “proceso” es sencillo y
eficiente.
Esta memoria no es persistente, y su
contenido se pierde al terminar la ejecución del programa. Por eso es necesario
guardar la información modificada si lo requieren las circunstancias. A esto lo
llamábamos “salida” en las páginas anteriores.
Una de las fortalezas de COBOL es la
descripción exhaustiva y detallada de la memoria del proceso. Es posible crear
variables sencillas y estructuras complejas de datos, moviendo con libertad la
información de unas a otras.
0.10. DECISIÓN Y REPETICIÓN
La otra característica relevante de
COBOL está relacionada con su capacidad para realizar las operaciones que
requiere la lógica del proceso.
En principio, las instrucciones que
codifica el programador se ejecutan en el orden en el que fueron escritas hasta
llegar al final, a una sentencia STOP RUN o a una instrucción GOBACK.
Este comportamiento puede modificarse
de dos maneras principales:
Decisión: Es posible forzar la
omisión de una o varias instrucciones en función del (in)cumplimiento de una
condición. Es el paradigma “Si ocurre esto, entonces haz esto, y en caso
contrario haz esto otro”.
Repetición: Es posible ejecutar
repetidamente una o varias instrucciones. Repetir un bloque de código tiene
mucho sentido si se requiere procesar un conjunto grande de cosas semejantes o
iguales.
1. IDENTIFICATION
1.1. ASPECTO
Para los más impacientes, veamos qué
aspecto tiene el código legible (el “fuente”) de un programa COBOL
sencillísimo:
identification division.
program-id. magnifico.
author. Javier Peces.
environment division.
configuration section.
input-output section.
data division.
file section.
working-storage section.
77 mensaje picture x(4) value 'HOLA'.
procedure division.
display mensaje.
stop run.
Aquí puedes ver ya
las cuatro divisiones que componen un programa COBOL.
Cada división está, a su vez,
compuesta por cero o más “secciones”.
Puedes observar que aparece un
“punto” al final de cada declaración, igual que en el lenguaje escrito natural.
Por ahora solamente nos pararemos a comentar lo mostrado en negrita.
Dentro de la división de
identificación:
– El nombre del
programa y su autor, son datos meramente informativos. Sólo es relevante el
nombre del fichero de texto “fuente” que contiene el código, “magnifico.cbl” en este caso.
En la división de datos:
– Una “variable”, es decir, una zona
de memoria reservada para almacenar cuatro caracteres alfanuméricos, accesible
mediante su nombre, “mensaje”, y con el contenido “HOLA” que se observa.
En la división de procedimientos:
– Una instrucción “DISPLAY” que sirve
para mostrar el contenido de la variable en la pantalla.
Cuando trabajes en un entorno
profesional, tal vez sea necesario codificar todo con letras mayúsculas.
1.2. OPEN COBOL
Puedes preguntarte cómo se va a
convertir el texto del programa anterior en algo utilizable en un sistema.
Salvo que tengas, por algún motivo, acceso al ordenador central de un banco y
los privilegios necesarios para crear, compilar y ejecutar programas.
Aquí entra en juego
OpenCobol, un compilador libre de lenguaje COBOL http://www.opencobol.org/ que puede funcionar en el PC de
casa. Encontrarás versiones para Linux, Mac y Windows.
También te puede interesar:
- MicroFocus Visual COBOL: http://www.microfocus.es/productos/micro-focus-developer/index.aspx
- Fujitsu NetCOBOL: http://www.netcobol.com/
- Interactive COBOL: http://www.icobol.com/
- COBOL for gcc: http://cobolforgcc.sourceforge.net/
·
Algunas de estas opciones son comerciales, es decir, de pago. Cada cual
conoce su economía y puede plantearse las elecciones de producto en función de
ella.
1.3. COMPILE, LINKEDIT, EXECUTE
A continuación, la secuencia básica
para instalar y probar OpenCobol en un PC con Debian o Ubuntu:
$ apt-cache search cobol
libcob1 - COBOL compiler -
runtime library
libcob1-dev - COBOL
compiler - development files
open-cobol - Compilador COBOL
$ sudo apt-get install open-cobol
...
$ vi magnifico.cbl
(copie, pegue y guarde el código de arriba)
$ cobc magnifico.cbl
$ cobcrun magnifico
HOLA
En esta primera prueba hemos usado
“cobcrun”, el módulo de ejecución (runtime) de OpenCobol. Como alternativa se
puede crear un ejecutable completo a partir del mismo código fuente:
$ cobc -x magnifico.cbl
$ ./magnifico
HOLA
2. ENVIRONMENT
2.1. LO ESENCIAL
En la esencia del COBOL subyace una
inquietud. Algún responsable informático de la Armada de los Estados Unidos (US
NAVY) se hartó, en un momento dado, de formar a sus técnicos en el uso de un
lenguaje diferente cada vez que se ponía en servicio una nueva computadora.
Esta peculiar situación requería
aplicar dos criterios de estandarización:
1. Tendría que ser posible usar los
mismos programas en distintas máquinas sin tener que volver a escribir el
código desarrollado con anterioridad. Para ello, todas las máquinas tendrían
que “entender” el lenguaje COBOL.
2. El programa no tendría que
preocuparse de las circunstancias concretas de su entorno. Para ello, se
requeriría un determinado nivel de abstracción, que hiciera independiente el
programa de los nombres y tamaños de los ficheros que procesa, de las características
de la máquina, etc.
Ambos objetivos se consiguieron sólo
parcialmente. La industria presionaba en el sentido contrario, y la tecnología
disponible sólo ayudaba en cierta medida.
2.2. DIVISIÓN DEL ENTORNO
Este peculiar nombre tiene más
sentido en inglés que en español. Es el segundo gran apartado de cada programa,
y contiene dos secciones llamadas CONFIGURATION e INPUT-OUTPUT:
environment division.
configuration section.
input-output section.
En la primera sección se especifican
tres cosas:
·
SOURCE-COMPUTER. Dónde se compiló el programa.
·
OBJECT-COMPUTER. Dónde se ejecuta.
·
SPECIAL-NAMES. Constantes del lenguaje.
Las dos primeras son poco más que
informativas, y en la tercera modificaremos, por ejemplo, el carácter que
separa los enteros de los decimales:
configuration
section.
special-names.
decimal-point is comma.
La sección de Entrada/Salida está
compuesta, a su vez, por dos párrafos que sirven para describir cada fichero
usado por el programa (FILE-CONTROL) y para informar sobre áreas compartidas de
la memoria (I-O-CONTROL).
environment
division.
configuration section.
input-output section.
file-control.
i-o-control.
Dentro de FILE-CONTROL aparecerá una
cláusula SELECT por cada fichero que use el programa.
En I-O-CONTROL se especifica el uso
compartido de determinadas áreas de memoria. Nos saltaremos con disimulo esa
parte.
2.3. SELECT
Esta partecita del programa es
importante porque permite independizar el código de su entorno. Internamente,
se harán las referencias a un fichero determinado con la palabra clave indicada
detrás de la palabra SELECT, sin mencionar para nada el nombre “real” del
fichero.
environment division.
input-output section.
file-control.
select CLIENTES
assign to EXT_ENV_CLIENTES.
En el caso de mi
Ubuntu, para que el programa manipule el fichero usando el nombre CLIENTES
podré llamarlo EXT_ENV_CLIENTES en el disco, o bien crear una variable de
entorno con ese nombre y el nombre real del fichero como contenido.
$ export EXT_ENV_CLIENTES="/tmp/custom/march.txt"
En sistemas IBM existen mecanismos
equivalentes. Pregunte o busque el término JCL (Job Control Language) para
hacerse una idea.
Además de la abstracción del nombre,
la cláusula SELECT documenta las características del fichero:
select
CLIENTES
assign to EXT_ENV_CLIENTES
organization indexed
access dynamic
record key CLAVE-CLIENTE
alternate record CLAVE-CLIENTE-ALT
file status FS-CLIENTES.
Ya hemos hablado brevemente de lo que
es un fichero, pero hay varios tipos y conviene que los detallemos “por
encima”.
2.4. FICHEROS SECUENCIALES
De manera nativa, los sistemas
operativos soportan “chorros” de datos (data streams) que los programas utilizan
para almacenar información de manera permanente en discos.
Enviando un carácter tras otro “al
chorro” se graban datos, y recuperándolos del mismo modo (uno tras otro) se
leen. Esto se conoce como “fichero secuencial”. Es necesario leer cada dato
para obtener el siguiente. Se recuperan en el mismo orden en el que se
grabaron.
Un poco rupestre ¿Verdad?
select SECUENCIAL
assign to
EXT_ENV_SECUENCIAL
organization sequential
access sequential
file status FS-SECUENCIAL.
2.5. FICHEROS DE ACCESO DIRECTO
En el mundo IBM y en otros sistemas
COBOL era habitual el uso de ficheros de “acceso directo”. En lugar de
“merendarse” todo el contenido del fichero para obtener un registro
determinado, se calcula la posición exacta del dato deseado y se accede a la
misma sin necesidad de manejar información innecesaria.
Extrañamente, encontrará documentados
como “random access” estos ficheros si consulta manuales en inglés.
select
DIRECTO
assign to EXT_ENV_DIRECTO
organization relative
access random
relative key CLAVE-DIRECTO
file status FS-DIRECTO.
2.5. FICHEROS INDEXADOS
El siguiente nivel de sofisticación
involucra uno de estos ficheros, accesible directamente, con otro secuencial
más pequeño que solamente contiene la información clave. Estos son los ficheros
“indexados”. Permiten acceder de forma sencilla a los datos sin la sobrecarga
derivada del método secuencial ni la complejidad del método directo.
Supongamos que guarda, no sin antes
estudiar la legislación vigente de protección de datos, la información personal
de sus clientes.
Imaginemos un dato que pueda
caracterizar de manera inequívoca a cada cliente: Su número de identificación
fiscal, pasaporte, seguridad social o permiso de conducir.
Será igual que el índice de un libro.
El valor del NIF permitirá desplazarse rápidamente a la “página del libro” en
la que se encuentra toda la información correspondiente a la persona en
cuestión.
Guardaremos en un fichero auxiliar
todos los NIF, asociando cada uno a un puntero a la “página” del fichero
principal en la que está cada bloque de datos personales.
Este fichero será relativamente
pequeño. Por tanto, procesarlo tendrá un coste moderado. Incluso podrá estar
enteramente en memoria durante la ejecución del programa.
Para leer o grabar la información de
un cliente se podrá especificar su NIF, y el programa encontrará mágicamente
los datos que le corresponden.
select INDEXADO
assign to EXT_ENV_INDEXADO
organization indexed
access random
relative key CLAVE-INDEXADO
file status FS-INDEXADO.
No obstante, podría resultar más
eficiente acceder al fichero secuencialmente si se desea procesar todos los
clientes.
Esta es una excelente excusa para
practicar la programación. Si el lector lo desea, dentro de poco tiempo podrá
desarrollar programas que accedan a los datos del mismo fichero, uno por la
clave y el otro secuencialmente “por la fuerza bruta”.
3. DATA
Este párrafo, y unos cuantos del
capítulo siguiente, están intencionadamente en blanco. Es para ver si están
ustedes atentos.
4. PROCEDURE
4.9. ACCESO A FICHEROS
Programando en lenguaje COBOL no
necesitaremos bucear en las interioridades del código nativo de la máquina.
En su lugar, usaremos verbos familiares de la lengua inglesa como OPEN,
READ, WRITE y CLOSE para obtener información contenida en ficheros y para
guardarla en los mismos.
·
OPEN: Prepara un fichero para su uso. Y además se asegura de que no lo
estropeamos por acceder a él desde varios programas al mismo tiempo.
·
READ: Obtiene un dato del fichero. Pronto veremos que los ficheros no se
procesan enteros, sino que se va leyendo la información poco a poco. La
unidad lógica más empleada se conoce como RECORD en inglés y REGISTRO en
español. Un fichero que contiene toda la información de los clientes está
compuesto por registros. Un registro almacena los datos de un solo cliente.
·
WRITE: Guarda un registro en un fichero.
·
CLOSE: Deja el fichero disponible para su uso.
4.10. MANIPULACIÓN DE DATOS
Las transformaciones realizadas en el
interior de la máquina superarán con mucho al simple picado que hace nuestra
máquina de la carne. Utilizaremos varios verbos, también muy familiares,
para manipular los datos una vez obtenidos.
Ejemplos de esto son:
·
MOVE, que copia el contenido de una variable a otra
·
ADD, para realizar sumas
·
SUBTRACT, para realizar restas
·
MULTIPLY, para hacer multiplicaciones
·
DIVIDE, para dividir
·
COMPUTE, la navaja suiza para realizar cálculos
4.11. LÓGICA DEL PROGRAMA
Es posible aplicar una ingente
cantidad de lógica para manipular la información, descartando la innecesaria,
seleccionando la que interesa y entregándola en el formato adecuado. Por
ejemplo, utilizaremos las instrucciones:
·
IF, ELSE y END-IF para tomar decisiones,
·
PERFORM y END-PERFORM para realizar acciones de manera agrupada o
repetitiva, y
·
EVALUATE con su correspondiente END-EVALUATE cuando la cosa se
complique.
Nada muy diferente de lo que se puede
hacer con cualquier otro lenguaje de programación.