| Bellacosa Mainframe e as quatro divisoes do cobol |
☕ Um Café no Bellacosa Mainframe
The Wild Wild COBOL — Quando James West Embarcou no Trem do z/OS, Artemus Gordon Vestiu um COMP-3 e o Dr. Loveless Tentou Sabotar a PROCEDURE DIVISION
Ou: o jovem padawan COBOL descobriu que as quatro divisões não são quatro fases de execução, um arquivo não é apenas um arquivo, WORKING-STORAGE não é um depósito de velharias — e nenhum agente secreto deveria atualizar o saldo antes de verificar o FILE STATUS
Prólogo — O trem que entrou no datacenter
Ano de 1965.
Enquanto o mundo assistia à Guerra Fria, à corrida espacial e à multiplicação de computadores empresariais, a televisão americana colocava nos trilhos uma série estranhíssima.
The Wild Wild West misturava faroeste, espionagem, ficção científica, invenções impossíveis, vilões megalomaníacos e agentes secretos que viajavam a bordo de um trem equipado como uma agência móvel de inteligência.
James West, interpretado por Robert Conrad, era o homem da ação. Artemus Gordon, vivido por Ross Martin, era inventor, estrategista e mestre dos disfarces. Ambos protegiam o presidente Ulysses S. Grant contra planos que normalmente começavam com uma pequena engrenagem e terminavam com alguma máquina destinada a dominar o país.
A série estreou em 17 de setembro de 1965 e durou quatro temporadas, com 104 episódios. A ideia era mais ou menos colocar “James Bond a cavalo”, acrescentar um laboratório dentro de um trem e soltar o Dr. Miguelito Loveless no ambiente de produção. The Wild Wild West — série de 1965
Agora imagine que James West receba uma nova missão:
“Agente West, alguém está alterando operações bancárias dentro do mainframe. O suspeito deixou quatro palavras na cena do crime:
IDENTIFICATION,ENVIRONMENT,DATAePROCEDURE.”
West verifica o revólver.
Artemus ajusta os óculos.
No fundo, começa a trilha de Richard Markowitz, misturando jazz, aventura e música de faroeste.
O trem parte para o datacenter.
1. Afinal, como “pensa” um programa COBOL?
Dizer que um programa “pensa” é uma metáfora.
O programa não possui consciência, intenção ou compreensão do negócio. Ele não olha para um campo chamado SALDO-CLIENTE e sente preocupação com o correntista.
O que ele faz é:
receber ou acessar dados;
interpretá-los conforme suas definições;
executar instruções;
verificar condições;
alterar estados;
produzir resultados;
informar sucesso ou erro ao ambiente.
Por isso, uma definição mais precisa seria:
Um programa COBOL processa informações segundo contratos de dados e regras procedurais previamente definidas.
Sua famosa organização em quatro divisões responde a quatro perguntas:
| Divisão | Pergunta |
|---|---|
IDENTIFICATION DIVISION | Quem sou? |
ENVIRONMENT DIVISION | Com quais recursos externos trabalharei? |
DATA DIVISION | Como minhas informações estão organizadas? |
PROCEDURE DIVISION | O que devo fazer? |
A IBM continua documentando essa estrutura no Enterprise COBOL moderno. As quatro divisões organizam o programa-fonte, embora nem todas precisem conter a mesma quantidade de elementos em todos os programas. IBM — COBOL program structure
Mas aqui encontramos a primeira armadilha do Dr. Loveless:
As quatro divisões não são quatro etapas executadas uma depois da outra.
O computador não executa a IDENTIFICATION DIVISION, entra na ENVIRONMENT DIVISION, passeia pela DATA DIVISION e finalmente chega à PROCEDURE DIVISION.
As três primeiras são essencialmente declarativas. Elas fornecem informações para que o compilador compreenda o programa.
A execução das instruções acontece na PROCEDURE DIVISION.
As quatro divisões são os compartimentos do trem. A PROCEDURE DIVISION é a locomotiva.
2. IDENTIFICATION DIVISION: os documentos do agente
Todo agente precisa de uma identidade:
IDENTIFICATION DIVISION.
PROGRAM-ID. PROCESSA-OPERACOES.O elemento central é o PROGRAM-ID, que identifica a unidade de programa.
Em códigos mais antigos, podemos encontrar:
AUTHOR. VAGNER BELLACOSA.
INSTALLATION. BANCO-WILD-WEST.
DATE-WRITTEN. 1965-09-17.Esses parágrafos documentais foram mais importantes em uma época anterior a Git, Endevor, Changeman, ISPW e outros sistemas de controle de versão e gerenciamento do ciclo de vida.
Hoje, manter um histórico completo de alterações dentro do fonte costuma provocar blocos enormes de comentários:
* ALTERADO POR FULANO EM 1987
* ALTERADO POR SICRANO EM 1994
* ALTERADO NOVAMENTE EM 2001
* NINGUÉM SABE QUEM ALTEROU EM 2007Esse tipo de comentário pode ser útil, mas não substitui um repositório confiável.
O que a divisão não faz
Ela não é executada como uma rotina.
O programa não começa dizendo:
Olá, sistema operacional.
Meu nome é PROCESSA-OPERACOES.
Fui escrito por Vagner.Sua função principal é identificar o programa para o compilador e para o ecossistema de desenvolvimento.
Dica do agente West
Ao analisar um fonte desconhecido, procure primeiro:
PROGRAM-ID.Depois procure:
comentários iniciais;
descrição funcional;
nomes de copybooks;
PROCEDURE DIVISION USING;programas chamados;
comandos CICS ou SQL.
O PROGRAM-ID mostra o nome. As interfaces mostram quem o programa realmente é.
Easter egg número 1
O programa de exemplo poderia se chamar:
PROGRAM-ID. NIGHT-OF-THE-COMP3.Os episódios de The Wild Wild West frequentemente começavam com “The Night of...”. Portanto, “The Night of the Packed Decimal” seria um episódio perfeitamente plausível no datacenter Bellacosa.
3. ENVIRONMENT DIVISION: o trem e os trilhos
James West e Artemus Gordon viajavam em seu próprio trem, o Wanderer, equipado com aposentos, armas, dispositivos e laboratório.
O trem era a plataforma operacional dos agentes.
No COBOL, a ENVIRONMENT DIVISION ajuda a descrever como o programa se relaciona com seu ambiente e, particularmente, com os arquivos utilizados.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ARQUIVO-ENTRADA
ASSIGN TO TRANSIN
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-STATUS-ENTRADA.
SELECT ARQUIVO-SAIDA
ASSIGN TO TRANSOUT
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-STATUS-SAIDA.Aqui existem diferentes níveis de nome:
ARQUIVO-ENTRADA: nome lógico conhecido pelo programa;TRANSIN: ligação externa;dataset: recurso físico fornecido durante a execução.
O JCL poderia conter:
//STEP01 EXEC PGM=PROCESSA
//STEPLIB DD DSN=BANCO.LOADLIB,DISP=SHR
//TRANSIN DD DSN=BANCO.OPERACOES.ENTRADA,DISP=SHR
//TRANSOUT DD DSN=BANCO.OPERACOES.SAIDA,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(10,5))O programa não precisa ter o nome físico BANCO.OPERACOES.ENTRADA gravado dentro do fonte.
Ele pede TRANSIN.
O ambiente entrega o dataset correspondente.
Isso permite executar o mesmo programa com diferentes arquivos:
//TRANSIN DD DSN=BANCO.OPERACOES.20260829,DISP=SHRou:
//TRANSIN DD DSN=BANCO.OPERACOES.20260830,DISP=SHRNenhuma recompilação é necessária.
Isso parece moderno?
É uma forma antiga e muito eficiente de separar:
código;
configuração;
recurso físico;
execução.
Em linguagens modernas, talvez alguém chamasse isso de configuração externa, abstração de recursos ou injeção de dependência.
No mainframe, o jovem padawan encontra o conceito dentro de um JCL escrito quando “cloud-native” ainda poderia significar um índio olhando para as nuvens antes de uma tempestade.
O contrato entre três partes
| Participante | Responsabilidade |
|---|---|
| COBOL | Declara o nome lógico e a forma de acesso |
| JCL ou subsistema | Associa o nome lógico ao recurso |
| Sistema operacional | Executa e controla o I/O |
Curiosidade
A ENVIRONMENT DIVISION não descreve tudo sobre o ambiente de produção.
Ela não contém necessariamente:
capacidade da LPAR;
política do WLM;
regras RACF;
configuração do sysplex;
parâmetros do CICS;
velocidade dos discos;
prioridade do job;
quantidade de memória disponível.
Por isso, dizer que ela “descreve onde o programa será executado” é didaticamente aceitável, mas amplo demais.
Ela descreve aspectos do ambiente relevantes ao COBOL, especialmente a relação com arquivos e dispositivos lógicos.
4. DATA DIVISION: o laboratório de Artemus Gordon
Artemus Gordon era o inventor e mestre dos disfarces.
Ele podia entrar num episódio como vendedor, cientista, militar, médico ou personagem improvável. O homem mudava a aparência, mas continuava sendo Artemus.
A DATA DIVISION possui algo dessa natureza: ela informa como sequências de bytes devem ser interpretadas.
Os mesmos bytes podem representar:
caracteres;
números;
datas;
valores monetários;
chaves;
indicadores;
registros;
tabelas;
áreas recebidas de outros programas.
A DATA DIVISION não é apenas um depósito de variáveis. É o laboratório onde bytes recebem forma e significado.
Ela pode conter seções como:
FILE SECTION;WORKING-STORAGE SECTION;LOCAL-STORAGE SECTION;LINKAGE SECTION.
Cada uma responde a uma necessidade diferente.
4.1 FILE SECTION: a planta dos vagões
A ENVIRONMENT DIVISION informa como localizar o trem.
A FILE SECTION informa como cada vagão está organizado.
DATA DIVISION.
FILE SECTION.
FD ARQUIVO-ENTRADA
RECORDING MODE IS F.
01 REGISTRO-ENTRADA.
05 IN-TIPO-OPERACAO PIC X.
05 IN-NUMERO-CONTA PIC 9(10).
05 IN-VALOR PIC 9(11)V99.
05 IN-DATA PIC 9(8).
05 IN-IDENTIFICADOR PIC X(20).O FD, ou File Description, descreve o arquivo para o programa.
O nível 01 descreve cada registro lido.
A diferença é importante:
| Elemento | Função |
|---|---|
SELECT | Declara a relação lógica com o arquivo |
FD | Descreve características do arquivo |
Registro 01 | Define o layout dos dados |
JCL DD | Fornece o dataset físico |
O perigo do vagão deslocado
Imagine que o arquivo contenha:
C00012345670000000012500020260830ABC123Se o layout estiver deslocado por uma posição, o programa pode interpretar:
parte da conta como valor;
parte do valor como data;
parte da data como identificador.
O arquivo existe. O job pode até começar. Mas os significados estarão errados.
Esse é um dos grandes ensinamentos do COBOL:
Dados não são apenas conteúdo; são conteúdo, posição, tamanho, formato e contexto.
4.2 WORKING-STORAGE SECTION: a bancada permanente
WORKING-STORAGE SECTION.
01 WS-CONTADORES.
05 WS-REGISTROS-LIDOS PIC 9(9) VALUE ZERO.
05 WS-APROVADOS PIC 9(9) VALUE ZERO.
05 WS-REJEITADOS PIC 9(9) VALUE ZERO.
01 WS-TOTAL-PROCESSADO PIC S9(13)V99 COMP-3
VALUE ZERO.
01 WS-STATUS-ENTRADA PIC XX.
01 WS-STATUS-SAIDA PIC XX.A WORKING-STORAGE guarda dados internos necessários ao processamento:
contadores;
acumuladores;
indicadores;
mensagens;
resultados intermediários;
chaves de pesquisa;
códigos de retorno;
áreas auxiliares;
tabelas internas.
Ela é a bancada de Artemus Gordon: engrenagens, tubos, ferramentas, documentos e explosivos que Igor jurou serem apenas “materiais de homologação”.
Cuidado com uma simplificação perigosa
Muitos iniciantes imaginam que a WORKING-STORAGE sempre nasce completamente limpa toda vez que o programa é chamado.
Isso não deve ser presumido sem compreender:
o ambiente de execução;
o ciclo de vida do módulo;
se o programa é inicial;
se é chamado repetidamente;
se utiliza
IS INITIAL;se há reutilização da área.
O comportamento da WORKING-STORAGE importa especialmente em subprogramas, aplicações residentes e ambientes CICS.
A regra prática é:
Inicialize explicitamente aquilo cujo valor inicial seja importante para a lógica.
INITIALIZE WS-CONTADORES
WS-TOTAL-PROCESSADOMas também compreenda o que INITIALIZE fará com cada categoria de campo. Não transforme o comando numa varinha mágica usada sem ler o layout.
4.3 LOCAL-STORAGE SECTION: uma bancada para cada missão
LOCAL-STORAGE SECTION.
01 LS-CONTADOR-TEMPORARIO PIC 9(4).
01 LS-VALOR-INTERMEDIARIO PIC S9(9)V99 COMP-3.A LOCAL-STORAGE é alocada a cada entrada no programa e liberada quando a execução retorna.
Ela é útil quando diferentes ativações precisam de áreas independentes, especialmente em situações recursivas ou reentrantes.
Podemos imaginar assim:
WORKING-STORAGE: laboratório instalado no trem;LOCAL-STORAGE: maleta nova entregue para esta missão;LINKAGE: documento recebido de outro agente.
A IBM distingue essas áreas pelo modo como o armazenamento é obtido e pelo ciclo de vida dos dados. IBM — Describing the data
4.4 LINKAGE SECTION: a mensagem secreta de Washington
LINKAGE SECTION.
01 LK-OPERACAO.
05 LK-CONTA PIC 9(10).
05 LK-VALOR PIC S9(11)V99 COMP-3.
05 LK-TIPO PIC X.
05 LK-CODIGO-RETORNO PIC XX.A LINKAGE SECTION descreve dados disponibilizados por outro componente.
PROCEDURE DIVISION USING LK-OPERACAO.O programa chamado conhece o layout, mas normalmente não é o proprietário original da área.
Outro programa poderia executar:
CALL 'VALOPER'
USING WS-OPERACAOO programa VALOPER receberia a área por meio da LINKAGE SECTION.
A metáfora correta
James West recebe uma mensagem cifrada do presidente Grant.
Ele não criou o papel.
Não é dono da pasta.
Mas precisa conhecer a estrutura da mensagem para interpretá-la.
A LINKAGE SECTION descreve essa mensagem.
Perigo de produção
Chamador e chamado precisam concordar sobre:
tamanho da área;
ordem dos campos;
representação;
sinal;
quantidade de casas decimais;
forma de passagem;
campos de retorno.
Se um programa define:
05 VALOR PIC S9(7)V99 COMP-3.e outro acredita receber:
05 VALOR PIC X(20).Artemus Gordon pode usar todos os disfarces disponíveis: o contrato continua incompatível.
5. PICTURE: o código secreto dos dados
Considere:
05 WS-VALOR PIC S9(7)V99 COMP-3.Esse campo diz muito mais do que “sou um número”.
S: possui sinal;9(7): comporta sete dígitos inteiros;V: possui ponto decimal implícito;99: possui duas casas decimais;COMP-3: usa representação decimal compactada.
O V não ocupa um byte físico. Ele informa a posição lógica do separador decimal.
Se o campo contiver os dígitos equivalentes a:
000012345o COBOL poderá tratá-los como:
1.234,45conforme o PICTURE.
Por que isso importa aos bancos?
Valores financeiros precisam de precisão decimal previsível.
Usar ponto flutuante binário indiscriminadamente pode introduzir aproximações inconvenientes para dinheiro. COBOL oferece representações de ponto fixo, e itens COMP-3 são tratados como decimais compactados para operações aritméticas. IBM — Numeric data formats
COMP-3 não é o cofre do presidente Grant
Ele não impede automaticamente:
estouro;
truncamento;
arredondamento indevido;
dado inválido;
erro de sinal;
campo insuficiente;
regra financeira incorreta.
Por exemplo:
01 WS-PEQUENO PIC 9(3).O campo só comporta três dígitos. Tentar colocar um valor maior exige compreender o comportamento da operação e as opções de compilação.
Dica Bellacosa
Para dinheiro, não pergunte apenas:
“Quantos bytes esse campo ocupa?”
Pergunte também:
qual é a moeda?
quantas casas decimais?
pode ser negativo?
qual é o maior valor permitido?
qual regra de arredondamento?
zero é válido?
espaços são possíveis na entrada?
dados negativos representam débito ou estorno?
O tipo físico é apenas metade do contrato. A semântica empresarial é a outra.
6. Níveis de dados: o trem dentro do trem
Os números 01, 05 e 10 indicam hierarquia:
01 CLIENTE.
05 CLIENTE-ID PIC 9(10).
05 CLIENTE-NOME.
10 CLIENTE-PRIMEIRO-NOME PIC X(20).
10 CLIENTE-SOBRENOME PIC X(30).
05 CLIENTE-ENDERECO.
10 CLIENTE-RUA PIC X(40).
10 CLIENTE-NUMERO PIC 9(6).
10 CLIENTE-CEP PIC 9(8).CLIENTE é um grupo.
CLIENTE-NOME é um subgrupo.
CLIENTE-SOBRENOME é um campo elementar.
Podemos mover o grupo:
MOVE CLIENTE-NOME TO NOME-IMPRESSAOou somente uma parte:
MOVE CLIENTE-SOBRENOME
TO SOBRENOME-IMPRESSAOCOBOL permite trabalhar com o registro completo e com suas partes.
Curiosidade: nome qualificado
Se existirem dois campos chamados NUMERO:
NUMERO OF CLIENTE-ENDERECOpodemos qualificá-los por sua estrutura superior.
Isso demonstra que o nome de um campo também pode depender de seu contexto.
7. Nível 88: quando um código vira regra de negócio
Veja:
01 WS-FIM-ARQUIVO PIC X VALUE 'N'.
88 FIM-DO-ARQUIVO VALUE 'S'.
88 HA-REGISTROS VALUE 'N'.O nível 88 cria nomes de condição.
Em vez de:
IF WS-FIM-ARQUIVO = 'S'podemos usar:
IF FIM-DO-ARQUIVOOutro exemplo:
01 WS-STATUS-CONTA PIC X.
88 CONTA-ATIVA VALUE 'A'.
88 CONTA-BLOQUEADA VALUE 'B'.
88 CONTA-ENCERRADA VALUE 'E'.A lógica torna-se expressiva:
IF CONTA-BLOQUEADA
MOVE 'OPERACAO NAO PERMITIDA'
TO WS-MENSAGEM
END-IFO nível 88 não costuma reservar outra área independente. Ele atribui significado a valores da variável associada.
O disfarce de Artemus Gordon
O byte físico contém B.
Para o computador, é um caractere.
Para o programa, significa CONTA-BLOQUEADA.
Para o negócio, significa que determinadas operações precisam ser impedidas.
Artemus não alterou o byte. Alterou a maneira pela qual nós o compreendemos.
8. PROCEDURE DIVISION: James West entra em ação
Aqui ficam as instruções executáveis:
PROCEDURE DIVISION.
0000-PRINCIPAL.
PERFORM 1000-INICIALIZAR
PERFORM 2000-PROCESSAR
UNTIL FIM-DO-ARQUIVO
PERFORM 3000-FINALIZAR
GOBACK.A estrutura revela um programa batch clássico:
inicializar;
processar;
finalizar;
devolver o controle.
1000-INICIALIZAR.
OPEN INPUT ARQUIVO-ENTRADA
OUTPUT ARQUIVO-SAIDA
IF WS-STATUS-ENTRADA NOT = '00'
DISPLAY 'ERRO NA ABERTURA: '
WS-STATUS-ENTRADA
MOVE 12 TO RETURN-CODE
GOBACK
END-IF
PERFORM 1100-LER-ENTRADA.Depois:
2000-PROCESSAR.
PERFORM 2100-VALIDAR
IF OPERACAO-VALIDA
PERFORM 2200-EFETIVAR
ELSE
PERFORM 2300-REJEITAR
END-IF
PERFORM 2400-GRAVAR-RESULTADO
PERFORM 1100-LER-ENTRADA.No final:
3000-FINALIZAR.
CLOSE ARQUIVO-ENTRADA
ARQUIVO-SAIDA
DISPLAY 'LIDOS: ' WS-REGISTROS-LIDOS
DISPLAY 'APROVADOS: ' WS-APROVADOS
DISPLAY 'REJEITADOS: ' WS-REJEITADOS.O erro do iniciante
O iniciante pode acreditar que o COBOL começa executando o primeiro parágrafo visualmente encontrado em qualquer ponto do fonte.
A execução começa na primeira instrução executável da PROCEDURE DIVISION, salvo particularidades e pontos de entrada definidos.
Organizar um parágrafo não é chamá-lo.
Este parágrafo:
EXPLODIR-TREM.
DISPLAY 'BOOM'.não será executado apenas porque existe. Ele precisa ser alcançado pelo fluxo, por exemplo:
PERFORM EXPLODIR-TREMIgor agradece a informação.
9. O ciclo clássico: ler, testar, processar, ler novamente
Um programa sequencial costuma seguir este modelo:
PERFORM LER-ENTRADA
PERFORM UNTIL FIM-DO-ARQUIVO
PERFORM PROCESSAR-REGISTRO
PERFORM LER-ENTRADA
END-PERFORMA primeira leitura ocorre antes do laço.
Isso garante que o programa só processe quando houver um registro disponível.
LER-ENTRADA.
READ ARQUIVO-ENTRADA
AT END
SET FIM-DO-ARQUIVO TO TRUE
NOT AT END
ADD 1 TO WS-REGISTROS-LIDOS
END-READ.O fim do arquivo não é necessariamente erro ou ABEND.
É uma condição esperada.
O programa lê até que o arquivo informe:
“Agente West, não existem mais passageiros.”
Então finaliza o processamento.
flowchart TD
A["Abrir arquivos"] --> B["Ler registro"]
B --> C{"Fim do arquivo?"}
C -- Não --> D["Validar e processar"]
D --> E["Gravar resultado"]
E --> B
C -- Sim --> F["Fechar e emitir totais"]A armadilha do último registro
Se o programa processar antes da primeira leitura, trabalhará com uma área ainda não preenchida corretamente.
Se esquecer a leitura ao final do laço, processará o mesmo registro para sempre.
O resultado pode ser um laço infinito, alto consumo de CPU ou um job aparentemente decidido a atravessar o continente sem parar em nenhuma estação.
10. O verdadeiro pensamento: estados e condições
Um programa COBOL não trabalha somente com linhas. Ele trabalha com estados:
arquivo fechado;
arquivo aberto;
registro disponível;
fim do arquivo;
operação válida;
operação rejeitada;
atualização pendente;
commit realizado;
rollback solicitado.
Considere:
EVALUATE TRUE
WHEN IN-CONTA = ZERO
PERFORM REJEITAR-CONTA
WHEN IN-VALOR <= ZERO
PERFORM REJEITAR-VALOR
WHEN IN-VALOR > WS-LIMITE
PERFORM ANALISAR-LIMITE
WHEN OTHER
PERFORM APROVAR-OPERACAO
END-EVALUATEO EVALUATE TRUE permite expressar uma cadeia organizada de condições.
Também podemos avaliar um campo diretamente:
EVALUATE IN-TIPO-OPERACAO
WHEN 'C'
PERFORM PROCESSAR-CREDITO
WHEN 'D'
PERFORM PROCESSAR-DEBITO
WHEN 'E'
PERFORM PROCESSAR-ESTORNO
WHEN OTHER
PERFORM REJEITAR-TIPO
END-EVALUATEO WHEN OTHER é a porta dos fundos.
Se ele não existir, uma entrada inesperada pode passar sem o tratamento necessário.
A pergunta de produção
Ao depurar, não pergunte somente:
“Qual foi a última linha executada?”
Pergunte:
“Em que estado o programa acreditava estar?”
Um incidente frequentemente ocorre porque o estado real e o estado imaginado pelo programa divergiram.
11. FILE STATUS: a mensagem escondida no bolso do vilão
Ao declarar:
FILE STATUS IS WS-STATUS-ENTRADAo programa recebe informações sobre o resultado das operações de arquivo.
Depois de OPEN, READ, WRITE, REWRITE ou CLOSE, deve avaliar o código quando necessário.
READ ARQUIVO-ENTRADA
EVALUATE WS-STATUS-ENTRADA
WHEN '00'
CONTINUE
WHEN '10'
SET FIM-DO-ARQUIVO TO TRUE
WHEN OTHER
DISPLAY 'ERRO DE LEITURA: '
WS-STATUS-ENTRADA
MOVE 12 TO RETURN-CODE
END-EVALUATEOs significados exatos dependem da organização e da operação, devendo ser consultados na documentação aplicável.
Não faça isso no saloon
READ ARQUIVO-ENTRADA
PERFORM PROCESSAR-REGISTROSem verificar o resultado, o programa pode processar uma área não atualizada ou tratar um erro como se fosse sucesso.
James West nunca entraria num quarto escuro sem verificar a janela.
Igor entra, atualiza o VSAM e pergunta depois.
12. O programa bancário completo
Considere uma operação contendo:
tipo;
conta;
valor;
data;
identificador único.
O fluxo poderia ser:
validar o tamanho e o formato;
validar o tipo;
verificar duplicidade;
localizar a conta;
verificar o estado da conta;
conferir saldo ou limite;
calcular o novo saldo;
atualizar a conta;
registrar auditoria;
confirmar a unidade de trabalho;
gerar a resposta.
Uma versão didática:
PROCESSAR-OPERACAO.
SET OPERACAO-VALIDA TO TRUE
PERFORM VALIDAR-TIPO
PERFORM VALIDAR-CONTA
PERFORM VALIDAR-VALOR
IF OPERACAO-VALIDA
EVALUATE IN-TIPO-OPERACAO
WHEN 'C'
ADD IN-VALOR TO WS-SALDO
MOVE '00' TO OUT-CODIGO
WHEN 'D'
IF WS-SALDO >= IN-VALOR
SUBTRACT IN-VALOR
FROM WS-SALDO
MOVE '00' TO OUT-CODIGO
ELSE
MOVE '51' TO OUT-CODIGO
END-IF
WHEN OTHER
MOVE '12' TO OUT-CODIGO
END-EVALUATE
END-IF.Mas este código ainda não representa um sistema financeiro completo.
Faltam assuntos como:
autorização;
concorrência;
bloqueio;
persistência;
duplicidade;
idempotência;
segurança;
auditoria;
commit;
rollback;
reconciliação;
recuperação após falha.
Idempotência: a mesma diligência não pode ser assaltada duas vezes
Se a mesma operação chegar novamente por causa de retry, o sistema precisa saber se deve repeti-la.
Um identificador único pode ajudar a reconhecer que ela já foi processada.
Sem isso, um retry de comunicação pode transformar um débito de R$100 em dois débitos de R$100.
O primeiro processamento foi correto.
O segundo também seguiu corretamente as instruções.
O resultado empresarial, porém, está errado.
13. COMMIT e ROLLBACK: quem fica com o dinheiro?
Em processamento transacional, alterar uma conta e registrar a operação precisam formar uma unidade coerente.
Imagine:
debitar a conta;
gravar o histórico;
atualizar a auditoria;
confirmar.
Se o sistema falhar entre os passos 1 e 2, o saldo poderia mudar sem existir histórico correspondente.
O controle transacional procura impedir esse tipo de estado parcial.
COMMIT: confirma as alterações;ROLLBACK: desfaz alterações da unidade de trabalho ainda não confirmadas.
O Dr. Loveless do retry
O retry não é um mecanismo automaticamente bondoso.
Se uma operação falha antes da confirmação, talvez seja seguro repeti-la.
Se o cliente apenas não recebeu a resposta, mas a operação já foi confirmada, repeti-la pode duplicar o efeito.
Por isso, sistemas críticos precisam distinguir:
a solicitação não chegou;
chegou, mas falhou;
foi processada e sofreu rollback;
foi confirmada;
foi confirmada, mas a resposta se perdeu.
O agente competente não pergunta apenas “deu erro?”.
Ele pergunta:
“Em qual lado do
COMMITestávamos quando o trem explodiu?”
14. Em CICS, James West não percorre o arquivo inteiro
Num programa batch, o fluxo frequentemente percorre muitos registros.
Em CICS, uma transação normalmente recebe uma solicitação, executa uma unidade curta de processamento e responde.
EXEC CICS READ
FILE('CONTAS')
INTO(WS-REGISTRO-CONTA)
RIDFLD(WS-CHAVE-CONTA)
UPDATE
RESP(WS-RESP)
END-EXECDepois:
EVALUATE WS-RESP
WHEN DFHRESP(NORMAL)
PERFORM PROCESSAR-CONTA
WHEN DFHRESP(NOTFND)
PERFORM TRATAR-CONTA-INEXISTENTE
WHEN OTHER
PERFORM TRATAR-ERRO-CICS
END-EVALUATEAqui, o código COBOL trabalha sob o controle de um gerenciador transacional.
O CICS participa de:
despacho da transação;
acesso a recursos;
controle de unidade de trabalho;
comunicação;
recuperação;
gerenciamento operacional.
COBOL não está sozinho no trem. O CICS é o chefe da ferrovia.
15. Com Db2, entra o especialista relacional
EXEC SQL
SELECT SALDO,
STATUS_CONTA
INTO :WS-SALDO,
:WS-STATUS-CONTA
FROM CONTAS
WHERE NUMERO_CONTA = :WS-CONTA
END-EXECDepois:
EVALUATE SQLCODE
WHEN ZERO
PERFORM PROCESSAR-CONTA
WHEN +100
PERFORM TRATAR-NAO-ENCONTRADA
WHEN OTHER
PERFORM TRATAR-ERRO-DB2
END-EVALUATECOBOL cuida do fluxo procedural e das regras.
Db2 cuida do acesso relacional, dos dados, índices, planos e mecanismos internos.
O programa não precisa saber em qual página física está a linha. Precisa saber:
o que solicitou;
quais host variables receberão os valores;
qual foi o
SQLCODE;qual ação tomar.
Dica do Artemus
Nunca trate todo SQLCODE diferente de zero como a mesma coisa.
“Não encontrado”, “aviso”, “deadlock”, “timeout” e “erro estrutural” não significam a mesma situação operacional.
Um agente secreto que chama todos os desconhecidos de “Dr. Loveless” terminará prendendo o condutor do próprio trem.
16. O programa que escrevemos não é exatamente o programa executado
Antes da execução existe uma cadeia:
expansão de copybooks;
processamento de diretivas;
tratamento de SQL, CICS ou outras extensões;
compilação;
geração do objeto;
link-edit ou bind;
criação do módulo de carga;
carregamento;
execução.
Quando escrevemos:
COPY CPYCONTA.o copybook é incorporado durante a preparação do fonte.
Quando escrevemos:
ADD WS-VALOR TO WS-TOTALa CPU não executa a palavra inglesa ADD. O compilador gera instruções adequadas à arquitetura e às representações envolvidas.
COBOL descreve a intenção; o compilador produz a mecânica.
Compiladores modernos também podem otimizar o código para explorar recursos atuais do IBM Z. Portanto, um fonte com aparência antiga não significa necessariamente execução com técnicas de 1965.
O trem pode ser clássico. A locomotiva não precisa ser a vapor.
17. Antigo não significa automaticamente simples
Programas COBOL antigos podem conter:
REDEFINES;OCCURS DEPENDING ON;arquivos VSAM;
múltiplos índices;
chamadas dinâmicas;
SQL;
CICS;
IMS;
MQ;
tabelas complexas;
copybooks aninhados;
lógica gerada;
regras acumuladas por décadas.
Veja um REDEFINES:
01 WS-RESPOSTA.
05 WS-RESPOSTA-BRUTA PIC X(20).
01 WS-RESPOSTA-DETALHADA
REDEFINES WS-RESPOSTA.
05 WS-CODIGO PIC XX.
05 WS-MENSAGEM PIC X(18).As duas estruturas interpretam a mesma área de armazenamento.
Artemus Gordon continua sendo o mesmo homem, mas agora aparece com outro disfarce.
O recurso é poderoso. Também pode ficar difícil de rastrear quando usado sem disciplina.
OCCURS: a lista de passageiros
01 WS-TABELA-TAXAS.
05 WS-TAXA OCCURS 10 TIMES.
10 WS-CODIGO-TAXA PIC XX.
10 WS-PERCENTUAL PIC 9V9999.Isso cria uma tabela com dez ocorrências.
Pode ser acessada assim:
MOVE 'TX' TO WS-CODIGO-TAXA(1)Em estruturas maiores, podem existir índices, pesquisas sequenciais e SEARCH ALL.
O iniciante deve entender que uma tabela COBOL não é um banco de dados. É uma estrutura repetida dentro de uma área de dados.
18. COBOL não é confiável por encantamento
A linguagem favorece descrições explícitas e processamento empresarial. Seu ecossistema amadureceu durante décadas. Porém, nenhum programa se torna confiável apenas por terminar suas frases com ponto.
COBOL também pode sofrer:
S0C7por dado decimal inválido;S0C4por referência indevida à memória;S0CBpor divisão por zero;falhas de arquivo;
erros Db2;
deadlocks;
timeouts;
truncamentos;
perda de precisão;
loops;
commits incorretos;
regras de negócio erradas.
O compilador pode aceitar perfeitamente:
ADD TAXA TO SALDOMesmo que a regra correta fosse:
SUBTRACT TAXA FROM SALDOSintaticamente correto.
Financeiramente desastroso.
Clareza também não vem automaticamente
Compare:
IF X = 'S'
PERFORM 9000
END-IFcom:
IF CLIENTE-ELEGIVEL
PERFORM CALCULAR-LIMITE
END-IFO segundo código apresenta intenção.
Use nomes que revelem o negócio:
VALIDAR-LIMITE-DA-CONTA;CALCULAR-JUROS;GRAVAR-OPERACAO-REJEITADA;TRATAR-CONTA-ENCERRADA.
Evite transformar a PROCEDURE DIVISION num mapa desenhado pelo Dr. Loveless depois de três garrafas de bourbon.
19. Passo a passo para ler um programa desconhecido
Passo 1 — Descubra a missão
Leia:
PROGRAM-ID;comentários funcionais;
nome do membro;
JCL que executa o programa;
documentação relacionada.
Pergunte: qual problema empresarial ele resolve?
Passo 2 — Mapeie entradas e saídas
Procure:
SELECT;FD;READ;WRITE;REWRITE;LINKAGE SECTION;PROCEDURE DIVISION USING;EXEC SQL;EXEC CICS;comandos MQ;
CALL.
Desenhe as fronteiras antes de estudar todos os detalhes.
Passo 3 — Ache o fluxo principal
Procure nomes como:
MAIN;PRINCIPAL;INICIO;INITIALIZE;PROCESS;TERMINATE;FINALIZAR.
Anote os principais PERFORM.
Passo 4 — Encontre as condições de controle
Procure:
níveis 88;
flags;
FILE STATUS;SQLCODE;RESP;RETURN-CODE;indicadores de fim.
Esses elementos mostram como o programa toma decisões.
Passo 5 — Localize as alterações permanentes
Onde ele:
grava arquivo?
atualiza Db2?
reescreve VSAM?
envia mensagem?
confirma a transação?
realiza rollback?
Esses são os pontos de maior risco.
Passo 6 — Siga o caminho infeliz
Não leia somente o cenário de sucesso.
Pergunte:
e se a conta não existir?
e se o arquivo não abrir?
e se o dado não for numérico?
e se houver deadlock?
e se a operação chegar duas vezes?
e se a resposta se perder depois do commit?
Passo 7 — Confirme o contrato físico
Confira:
tamanho dos campos;
PIC;USAGE;sinal;
casas decimais;
alinhamento;
copybooks;
encoding;
definição no sistema externo.
Passo 8 — Só então aprofunde cada parágrafo
Depois de compreender o mapa, siga as rotinas em detalhe.
Ler um programa grande da linha 1 até a linha 20.000 sem criar um mapa é como procurar o Dr. Loveless revistando cada parafuso do trem.
20. Curiosidades escondidas no vagão de bagagens
Curiosidade 1 — A série e o COBOL pertencem à mesma era cultural
COBOL surgiu no final dos anos 1950 e se consolidou nos anos 1960. The Wild Wild West estreou em 1965.
Os dois refletem, de maneiras diferentes, uma era fascinada por organizações, máquinas, automação, espionagem e tecnologia.
Curiosidade 2 — O tema musical também é híbrido
A música de Richard Markowitz combinava elementos de jazz e do faroeste. A série precisava soar simultaneamente clássica e moderna.
COBOL também é uma combinação curiosa:
palavras quase naturais;
layouts rígidos;
representação binária e decimal;
regras comerciais;
execução em hardware extremamente sofisticado.
Curiosidade 3 — Artemus Gordon usou dezenas de disfarces
Ross Martin transformou o personagem num mestre de caracterização. Em COBOL, REDEFINES permite que uma mesma área seja interpretada de maneiras diferentes.
Não significa que REDEFINES foi inspirado por Artemus. Mas o Easter egg é bom demais para ser desperdiçado.
Curiosidade 4 — O primeiro ano foi em preto e branco
A primeira temporada da série foi filmada em preto e branco; as seguintes passaram para cores.
O fonte COBOL também pode parecer monocromático numa listagem antiga, mas ferramentas modernas oferecem navegação, análise, refatoração assistida, integração com Git e depuração visual.
Curiosidade 5 — O ponto pode ser mais perigoso que o revólver
Em COBOL, o ponto encerra uma sentença e pode terminar escopos implícitos.
Código moderno costuma preferir terminadores explícitos:
IF CONDICAO
PERFORM ACAO
ELSE
PERFORM OUTRA-ACAO
END-IFUse períodos com consciência. Um ponto colocado no local errado pode alterar o fluxo de uma estrutura.
Easter egg número 2
Se encontrar isto:
88 LOVELESS-ESTA-PRESENTE VALUE 'S'.não execute:
SET IGNORAR-FILE-STATUS TO TRUEO vilão já entrou no programa.
21. O mapa mental definitivo
A versão simples é:
Definir dados → processar → obter resultadoA versão profissional é:
Identificar o programa
↓
Estabelecer contratos externos
↓
Descrever dados e representações
↓
Inicializar o estado
↓
Receber ou ler informações
↓
Validar estrutura e conteúdo
↓
Aplicar regras de negócio
↓
Alterar o estado de forma controlada
↓
Tratar condições e exceções
↓
Confirmar ou desfazer
↓
Gerar resultado, auditoria e código de retornoCOBOL não trabalha apenas com valores.
Trabalha com contratos e consequências.
Uma data não é somente PIC 9(8).
Precisamos saber:
está em
AAAAMMDD?zero significa ausência?
a data deve existir no calendário?
aceita data futura?
qual fuso horário está envolvido?
Um valor não é somente PIC S9(11)V99 COMP-3.
Precisamos saber:
qual moeda?
qual limite?
pode ser negativo?
como arredondar?
débito e crédito usam o mesmo sinal?
um estorno deve inverter ou criar nova operação?
O layout diz como ler os bytes.
A regra de negócio diz o que esses bytes significam.
Epílogo — A noite em que o mainframe não improvisou
James West encontrou o Dr. Loveless no último vagão.
Diante dele havia uma máquina gigantesca, engrenagens, luzes e um cartão perfurado com uma única instrução:
MOVE WS-SALDO-DO-BANCO
TO WS-CONTA-DO-LOVELESS.— Um plano brilhante — disse Loveless. — Em poucos minutos, todo o dinheiro estará em minha conta!
Artemus Gordon examinou o programa.
— Receio que exista um problema, doutor.
— Impossível!
— O senhor não declarou corretamente o campo receptor. Também ignorou o FILE STATUS, não verificou o SQLCODE, não criou controle de duplicidade e tentou atualizar o saldo fora de uma unidade de trabalho.
James West sorriu:
— Além disso, o job terminou com COND CODE 0012.
A trilha de Richard Markowitz acelerou.
Loveless puxou uma alavanca.
O trem começou a tremer.
Igor, escondido atrás da WORKING-STORAGE, gritou:
— Eu avisei que PIC 9(3) não comportava um milhão!
O jovem padawan finalmente compreendeu.
As quatro divisões não representavam quatro pensamentos executados sequencialmente. Eram quatro maneiras de organizar o conhecimento necessário para construir o programa:
identidade;
ambiente;
dados;
procedimento.
Mas o verdadeiro “pensamento” do COBOL acontecia na interação entre:
registros;
estados;
condições;
regras;
operações;
códigos de retorno;
commits;
rollbacks.
COBOL não adivinha.
Não improvisa.
Não olha para 000001250 e conclui que provavelmente significa R$12,50.
Alguém precisa declarar a escala, o sinal, a representação e a regra.
É justamente essa disciplina que continua ensinando algo valioso depois de mais de seis décadas:
Em sistemas críticos, clareza não é enfeite colocado depois que o programa funciona. Clareza faz parte do mecanismo que impede o trem de descarrilar.
James West cuidava da ação.
Artemus Gordon compreendia os disfarces.
O JCL preparava os trilhos.
O z/OS controlava a ferrovia.
E o jovem programador COBOL, agora um pouco menos padawan, finalmente aprendeu a regra fundamental do Oeste Selvagem Digital:
Antes de sacar o
WRITE, verifique oFILE STATUS. Antes de atualizar o saldo, conheça o contrato. E, quando o Dr. Loveless oferecer umGO TOpara uma rotina que ninguém encontra, peça primeiro o mapa do fluxo.
Sem comentários:
Enviar um comentário