5 diferenças que surpreendem quem sai do Linux e vai para o Mainframe

Você programou usando GnuCOBOL ou MF-Cobol no Linux ou no Windows, trabalhou com arquivos sequenciais e indexados, criou tabelas internas, utilizou PERFORM, IF, EVALUATE e talvez até tenha desenvolvido aplicações completas.

Mas existe uma pergunta que costuma surgir quando alguém decide buscar oportunidades no ambiente mainframe: esse conhecimento é suficiente? O COBOL que roda em uma plataforma realmente é semelhante ao que roda na outra?

Neste artigo, vamos explorar as principais diferenças entre o GnuCOBOL e o IBM COBOL for z/OS para entender até que ponto a experiência adquirida no Linux prepara você para trabalhar no mundo dos mainframes.

Diferença #1: A linguagem é “praticamente” a mesma

A maior parte da sintaxe que você estudou e praticou continuará válida em um ambiente mainframe.

Comandos como MOVE, IF, EVALUATE, PERFORM, COMPUTE, READ, WRITE e OPEN funcionam da mesma maneira tanto no GnuCOBOL quanto no IBM COBOL for z/OS.

As quatro divisões clássicas da linguagem também permanecem as mesmas: IDENTIFICATION DIVISION, ENVIRONMENT DIVISION, DATA DIVISION e PROCEDURE DIVISION.

Da mesma forma, conceitos fundamentais como registros, tabelas, níveis 01, 05 e 88, variáveis numéricas e alfanuméricas, além das estruturas de controle de fluxo, fazem parte do dia a dia em ambas as plataformas.

Isso significa que o investimento feito para aprender a linguagem não é perdido ao migrar para o mainframe. Um programador COBOL experiente consegue ler e compreender todos os programas escritos para z/OS mesmo que nunca tenha trabalhado nesse ambiente.

Essa semelhança, no entanto, pode criar uma falsa impressão de que tudo funciona exatamente da mesma forma. É quando começamos a sair da sintaxe e entrar nos detalhes do ambiente de execução que as diferenças mais importantes começam a aparecer.

E a primeira delas está justamente em algo que todo programa utiliza: arquivos.

Diferença #2: No mainframe, o programa não sabe onde está o arquivo

No Linux ou no Windows, a gente pode codificar a cláusula SELECT na ENVIRONMENT DIVISION com a seguintes sintaxe:

SELECT CLIENTES ASSIGN TO "~/dat/cliente.txt".

Ou seja, o programa estabelece exatamente onde o arquivo está ou estará.

Já no mainframe, o que normalmente a gente encontra é…

SELECT CLIENTES ASSIGN TO CLIENTES.

O nome físico do arquivo CLIENTES não está no programa. Ele é informado externamente, na maioria das vezes, pelo JCL que está executando o programa:

//EXEC01 EXEC PGM=PROG1
//CLIENTES DD DSN=EMPRESA.PROD.CLIENTES,
//                DISP=SHR

O programa PROG1 acessa um arquivo que ele chama internamente de CLIENTES, mas o nome real do arquivo (EMPRESA.PROD.CLIENTES) quem define é o JCL.

No Linux, o equivalente a essa estrutura seria associar o arquivo a uma variável de ambiente para que,  externamente, um script associe essa variável de ambiente ao nome real do arquivo.

Algo parecido com uma declaração assim no COBOL…

SELECT CLIENTES ASSIGN TO "$CLIENTES".

E no script…

export CLIENTES="~/dat/clientes.txt"
PROG1

Diferença #3: No mainframe, um dataset não é apenas um arquivo

No Linux, um arquivo é só um arquivo. Você declara ele na ENVIRONMENT, define na DATA DIVISION, dá um tamanho para o nível 01 da FD, dá um OPEN OUTPUT na PROCEDURE e pronto, o arquivo está criado.

No z/OS, um dataset (como normalmente os arquivos são chamados) possui características definidas no próprio sistema operacional:

  • Tamanho do registro
  • Formato do registro
  • Tamanho do bloco de registros
  • Quantidade de cilindros (ou trilhas) que o arquivo ocupará no primeiro momento
  • Quantidade de cilindros (ou trilhas) que será adicionada ao arquivo quando ele expandir
  • Organização do dataset
  • Etc.

Essas informações existem independentemente do programa COBOL, ou do programa que vai processar o arquivo, independentemente da linguagem.

Enquanto no Linux um arquivo pode conter linhas de tamanhos variados, com um caracter invisível x’0A’ no final de cada registro, no mainframe o formato físico dos registros faz parte da definição do dataset.

O que isso significa em termos de sintaxe? Não muito. SELECT, FD, OPEN, READ, WRITE e CLOSE se comportam da mesma maneira, mas entender essa diferença é fundamental para quem pretende trabalhar com processamento batch na plataforma mainframe.

Principalmente quando precisar descobrir a causa de erros de execução que não costumavam ocorrer no Linux.

Diferença #4: Nem todo arquivo sequencial é um arquivo texto

Se você aprendeu COBOL no Linux ou no Windows, provavelmente trabalhou diversas vezes com arquivos definidos como LINE SEQUENTIAL, definido assim:

SELECT CLIENTES ASSIGN TO "$CLIENTES"
ORGANIZATION IS LINE SEQUENTIAL.

Essa organização é bastante conveniente no Linux e no Windows porque permite visualizar o conteúdo do arquivo com ferramentas comuns do sistema operacional, como cat, less, vim ou no bloco de notas.

Cada registro é armazenado em uma linha do arquivo, separada por um caractere de fim de linha (x’0a’ no caso do Linux, também conhecido como LF) ou dois caracteres (x’0d0a’ no caso do Windows, também conhecidos como CR LF).

Essa abordagem é simples, intuitiva e muito prática.

No ambiente mainframe, entretanto, esse não costuma ser o formato mais utilizado. O mais comum é encontrar arquivos definidos como:

SELECT CLIENTES ASSIGN TO CLIENTES
ORGANIZATION IS SEQUENTIAL.

Em termos de código, a diferença é pequena. Afinal, ambos são arquivos sequenciais e ambos são processados registro a registro. No entanto, a forma como os dados são armazenados é bastante diferente.

Enquanto no arquivo `LINE SEQUENTIAL` do Linux, o fim de cada registro é identificado por caracteres de quebra de linha gravados no arquivo.

Já no arquivo `SEQUENTIAL` do mainframe, cada registro possui tamanho pré-definido e é armazenado de acordo com as características físicas do dataset.

Por isso, ao migrar do Linux para o mainframe, uma das primeiras mudanças de perspectiva é deixar de pensar em “linhas de texto” e passar a pensar em blocos de registros de tamanho fixo. Essa diferença sutil influencia a forma como arquivos são criados, transferidos, processados e administrados no ambiente corporativo.

E sim, é possível criar arquivos puramente SEQUENTIAL no LINUX, e ele vai ter comportamento semelhante ao arquivo SEQUENTIAL do mainframe. Não é comum que a gente faça isso, pelos motivos que comentei nos parágrafos anteriores, mas é possível.

O contrário, porém, não é verdade. No mainframe só faz sentido criar um arquivo LINE SEQUENTIAL se ele for (ou estiver) armazenado no z/OS UNIX System Services (USS), que é o ambiente POSIX/UNIX do z/OS.

Diferença #5: No mainframe, nem toda manipulação de arquivos acontece dentro do COBOL

Essa costuma surpreender bastante.

No Linux, quando precisamos ordenar um arquivo, copiar registros, selecionar dados ou gerar arquivos intermediários, nossa tendência natural é escrever um programa COBOL.

Por exemplo, para ordenar um arquivo, podemos utilizar o comando SORT da própria linguagem:

SORT WRK-CLIENTES
ON ASCENDING KEY WRK-CLI-NOME
USING ENT-CLIENTES
GIVING SAI-CLIENTES.

No ambiente mainframe, entretanto, existe uma tradição muito forte de delegar operações sobre arquivos para utilitários especializados.

Em muitos casos, um desenvolvedor experiente nem sequer escreveria um programa COBOL para realizar a ordenação de um arquivo. Ao invés disso, utilizaria ferramentas como DFSORT ou SYNCSORT diretamente no JCL, como no exemplo abaixo:

//ORDENA EXEC PGM=SORT
//SORTIN DD DSN=EMPRESA.PROD.CLIENTES,
//              DISP=SHR
//SORTOUT DD DSN=EMPRESA.PROD.CLIENTES.ORD,
//              DISP=(NEW,CATLG,DELETE),
//              SPACE=(CYL,(1,1)),
//              DCB=(RECFM=FB,LRECL=45)
//SYSOUT DD SYSOUT=*
//SYSIN DD *
  SORT FIELDS=(6,30,CH,A)
/*

E a mesma abordagem seria adotada para remover registros duplicados, filtrar registros, reorganizar layouts, mesclar arquivos etc. Tudo isso pode ser feito por utilitários específicos, sem uma única linha de COBOL.

Para quem vem do Linux, essa mudança de mentalidade costuma ser inesperada. Afinal, a tendência é imaginar que qualquer transformação de dados exige um programa. No mundo mainframe, muitas vezes a solução mais eficiente é utilizar uma ferramenta já existente e deixar o COBOL apenas para a lógica de negócio.

Isso não significa que o comando SORT desaparece no mainframe. Ele continua existindo e sua sintaxe é praticamente a mesma (no caso do GnuCobol existe uma diferença no comando RETURN que eu não engulo até hoje, mas essa é outra história).

A diferença é que o ecossistema mainframe oferece um conjunto muito maior (e muito mais eficiente) de ferramentas voltadas especificamente para manipulação de arquivos em larga escala.

Conclusão

A maior parte das diferenças não está na linguagem COBOL em si, mas na forma como os arquivos são armazenados, organizados e processados.

O programador COBOL que usa GnuCOBOL ou MF-COBOL, no Linux ou no Windows, domina quase tudo o que precisa para definir layouts, processar registros, gerar relatórios, realizar operações aritméticas, trabalhar com tabelas internas e arquivos indexados, tratar strings etc.

O que muda ao chegar ao mainframe é a infraestrutura que existe ao redor desses programas e a maneira como ela influencia o tratamento dos dados.

Se você quiser entender um pouco mais sobre o que é um mainframe e como ele funciona, eu escrevi um livro só sobre esse assunto. Você pode solicitar gratuitamente sua cópia em PDF clicando nesse link.

Quem já domina os fundamentos da linguagem não precisa reaprender COBOL; precisa apenas compreender como o ambiente z/OS implementa conceitos que, em Linux, normalmente são tratados de forma diferente.