✨ Bem-vindo ao meu espaço! ✨
Este blog é o diário de um otaku apaixonado por animes, tecnologia de mainframe e viagens.
Cada entrada é uma mistura única: relatos de viagem com fotos, filmes, links, artigos e desenhos, sempre buscando enriquecer a experiência de quem lê.
Sou quase um turista profissional: adoro dormir em uma cama diferente, acordar em um lugar novo e registrar tudo com minha câmera sempre à mão.
Entre uma viagem e outra, compartilho também reflexões sobre cultura otaku/animes
Bellacosa Mainframe e as variaveis computacionais do COBOL
☕💣🚀 COMP-1, COMP-2, COMP-3, COMP-4 e COMP-5 para o Programador COBOL Jr.
Uma das maiores fontes de confusão para quem começa em COBOL é entender por que existem tantos tipos numéricos.
A resposta está na história dos mainframes IBM.
Cada COMP surgiu para resolver um problema específico de armazenamento, desempenho ou precisão matemática. (IBM)
Linha do Tempo
Tipo
Surgiu
COMP
Década de 1960
COMP-1
Década de 1970
COMP-2
Década de 1970
COMP-3
Década de 1960
COMP-4
Década de 1970
COMP-5
Década de 1980
Os números exatos variam conforme compilador e plataforma, mas COMP-3 e COMP já existiam nos ambientes System/360. COMP-1, COMP-2 e COMP-4 apareceram como extensões IBM. COMP-5 surgiu posteriormente para resolver limitações do BINARY tradicional. (IBM)
Bellacosa Mainframe apresenta as variavis numericas do cobol comp
Bellacosa Mainframe iniciando no EBCDIC e cartão perfurado
☕ Um Café no Bellacosa Mainframe
EBCDIC: O Código que o Mundo Chama de Legado, Mas que Ainda Move Bilhões de Transações Todos os Dias
"Quem ri do EBCDIC normalmente nunca precisou garantir que um banco inteiro fechasse o balanço sem perder um único centavo."
Existe um momento na vida de praticamente todo programador que começa a trabalhar com Mainframe.
Você recebe um arquivo vindo do z/OS.
Abre no Notepad.
E aparece algo parecido com isto:
ÁêØ¢ËÑÇ@@@âÑÄÅ...
A primeira reação costuma ser:
"O arquivo está corrompido."
A segunda:
"Alguém esqueceu de salvar em UTF-8."
A terceira:
"Isso é tecnologia dos dinossauros."
Nenhuma delas está correta.
Na verdade, aquele arquivo está absolutamente perfeito.
O problema é que você está tentando ler um livro escrito em outro alfabeto.
Esse alfabeto chama-se EBCDIC (Extended Binary Coded Decimal Interchange Code).
E, apesar de muita gente tratá-lo como uma curiosidade histórica, ele continua presente nos maiores bancos, seguradoras, governos e companhias aéreas do planeta.
Hoje vamos tomar um café e desmistificar um dos assuntos mais mal compreendidos do universo IBM Z.
Bellacosa Mainframe apresenta o ebcdic
O maior mito sobre o EBCDIC
Pergunte para dez desenvolvedores que nunca trabalharam com Mainframe:
"Por que existe EBCDIC?"
As respostas costumam ser parecidas.
"Porque a IBM queria prender os clientes."
É uma boa história.
Mas é falsa.
Quando o EBCDIC nasceu, em 1963, praticamente ninguém utilizava ASCII.
Aliás...
Nem mesmo o ASCII era um padrão consolidado.
Cada fabricante possuía sua própria codificação.
Burroughs.
Honeywell.
CDC.
UNIVAC.
ICL.
Todos tinham soluções próprias.
A IBM simplesmente continuou evoluindo aquilo que ela já utilizava desde os computadores baseados em cartões perfurados.
Não era uma conspiração.
Era evolução tecnológica.
O mundo era completamente diferente
Hoje pensamos em computadores conectados pela Internet.
Em 1963...
Não havia Internet.
Não havia Wi-Fi.
Não havia APIs.
Não havia JSON.
Muito menos ChatGPT.
O computador era uma máquina corporativa.
Seu trabalho era processar:
folhas de pagamento;
contas bancárias;
extratos;
impostos;
seguros;
notas fiscais;
cartões perfurados.
O objetivo não era conversar com outros computadores.
Era processar documentos com absoluta confiabilidade.
Essa diferença muda tudo.
ASCII nasceu para conversar
O ASCII descende do Código Baudot, criado para telegrafia.
Imagine um cabo atravessando centenas de quilômetros.
Cada bit enviado custava tempo.
Tempo custava dinheiro.
Por isso o ASCII foi pensado para transmissão serial.
Seu projeto privilegiava simplicidade eletrônica.
Existe uma curiosidade fantástica.
Observe:
A = 65
a = 97
A diferença entre as duas letras é praticamente um único bit.
Isso permitia que um circuito eletrônico transformasse letras maiúsculas em minúsculas simplesmente alterando um sinal elétrico.
Hoje parece detalhe.
Na época era genial.
Enquanto isso...
Na IBM...
O problema era outro.
Ela precisava representar cartões perfurados.
E aí entra um personagem quase esquecido da computação moderna.
Bellacosa Mainframe e a anatomia de um cartão perfurado
O cartão perfurado
Imagine uma folha de papel rígido.
Ela possui 80 colunas.
Cada coluna representa um caractere.
Cada coluna possui 12 posições possíveis para perfuração.
12
11
0
1
2
3
4
5
6
7
8
9
As três primeiras posições eram chamadas de Zona.
As demais eram os Dígitos.
Para escrever uma letra não bastava perfurar um único lugar.
Era necessário combinar uma zona com um dígito.
Por exemplo:
Zona 12 + Dígito 1 = A
Esse padrão tornou-se tão importante que a IBM decidiu preservá-lo quando criou o System/360.
O nascimento do EBCDIC
Em vez de inventar um alfabeto completamente novo...
A IBM fez algo extremamente inteligente.
Ela traduziu a lógica física do cartão diretamente para um byte.
Cada caractere passou a ocupar:
4 bits
+
4 bits
Ou seja:
Nibble superior
↓
Zona
Nibble inferior
↓
Dígito
É por isso que o EBCDIC parece "bagunçado".
Na verdade...
Ele apenas respeita a lógica física do cartão.
O famoso buraco entre I e J
Essa é uma das primeiras coisas que um curioso percebe.
No ASCII temos:
ABCDEFGHIJKLMN...
Tudo contínuo.
Já no EBCDIC acontece algo diferente.
As letras ficam divididas em blocos.
A até I
↓
salto
↓
J até R
↓
salto
↓
S até Z
Por quê?
Porque era exatamente assim que funcionava o cartão perfurado.
O que parece estranho hoje fazia todo sentido em 1964.
O EBCDIC não é uma tabela.
Ele é uma filosofia.
Essa talvez seja a maior diferença.
ASCII resolve um problema.
Representar caracteres.
O EBCDIC fazia parte de uma arquitetura inteira.
Quando a IBM lançou o System/360 ela criou uma plataforma capaz de durar décadas.
E conseguiu.
Hoje, mais de sessenta anos depois, conceitos daquela arquitetura continuam presentes no IBM Z.
Entre eles:
canais de I/O;
processamento batch;
registros de tamanho fixo;
decimal compactado;
formatos de impressão;
arquivos VSAM;
e o EBCDIC.
Nada disso surgiu isoladamente.
Tudo fazia parte da mesma visão de engenharia.
"Então por que não mudar para UTF-8?"
Essa pergunta aparece em praticamente toda palestra.
A resposta curta é:
Porque não faz sentido.
Imagine um banco.
Ele possui cinquenta anos de software.
Bilhões de linhas em:
COBOL;
PL/I;
Assembler.
Agora imagine alterar a representação interna dos caracteres.
O que precisaria ser testado?
Tudo.
Literalmente tudo.
Comparações.
Ordenações.
Relatórios.
Impressoras.
Interfaces.
Conversões.
Milhões de programas.
Décadas de auditoria.
Bilhões de registros históricos.
O custo seria gigantesco.
O benefício?
Praticamente nenhum.
O IBM Z odeia UTF-8?
Muito pelo contrário.
Esse é outro mito.
Hoje o IBM Z executa naturalmente:
Java;
Python;
Node.js;
Go;
C/C++;
OpenJDK;
OpenSSH;
Linux on Z;
Docker;
Kubernetes;
APIs REST;
GraphQL;
OpenAPI.
Todos utilizando UTF-8.
O segredo está na arquitetura.
As aplicações modernas trabalham em UTF-8.
Os componentes tradicionais continuam utilizando EBCDIC.
Entre eles:
COBOL;
CICS;
IMS;
DB2;
arquivos sequenciais.
No meio do caminho existem conversores.
Tudo acontece automaticamente.
Na maioria das vezes o desenvolvedor nem percebe.
Um exemplo simples
Imagine um aplicativo no celular.
Cliente
↓
API REST
↓
z/OS Connect
↓
COBOL
↓
DB2
O celular envia UTF-8.
O z/OS Connect converte.
O COBOL recebe EBCDIC.
Na volta acontece exatamente o contrário.
Para quem usa o aplicativo...
Nada muda.
Curiosidade nº 1
Existe apenas um EBCDIC?
Não.
Existem centenas.
São chamadas de Code Pages.
Algumas famosas:
CP037
CP500
CP273
CP1047
CP1140
Cada uma adapta caracteres para determinados idiomas.
É parecido com as antigas páginas de código do Windows.
Curiosidade nº 2
Nem todo problema é "EBCDIC".
Muitas vezes o arquivo já está em EBCDIC.
Mas você está usando a página errada.
É como abrir um texto em português utilizando uma fonte chinesa.
Os bytes continuam corretos.
A interpretação é que muda.
Curiosidade nº 3
COBOL também depende do EBCDIC.
Quando você escreve:
IF CLIENTE-A > CLIENTE-B
Ou executa:
SORT
Existe uma sequência de classificação.
Essa sequência depende da codificação utilizada.
No Mainframe ela normalmente segue o EBCDIC.
Isso significa que uma ordenação feita no Windows pode produzir resultados diferentes daquela executada no z/OS.
Curiosidade nº 4
No ASCII:
9
↓
A
↓
a
No EBCDIC...
A ordem muda.
Esse pequeno detalhe já causou inúmeros bugs em integrações entre plataformas.
Curiosidade nº 5
Você provavelmente usa EBCDIC sem perceber.
Quando um banco expõe uma API REST.
Quando um PIX consulta uma conta.
Quando um cartão de crédito é autorizado.
Quando uma companhia aérea consulta uma reserva.
Quando um caixa eletrônico responde.
Existe uma enorme chance de existir um programa COBOL falando EBCDIC em algum lugar da infraestrutura.
Easter Egg para Padawans 🥚
Se você assistir ao filme Apollo 13, verá computadores IBM em operação.
Se visitar museus de computação encontrará cartões perfurados.
Se estudar a arquitetura do System/360 descobrirá que muitas decisões tomadas naquela época continuam influenciando os processadores IBM Z atuais.
É como encontrar fósseis vivos.
Só que ainda processando bilhões de dólares por dia.
Outro Easter Egg
O EBCDIC costuma ser chamado de "dinossauro".
Mas existe uma ironia divertida.
Grande parte das aplicações modernas utiliza JSON.
JSON é texto.
Texto precisa de codificação.
Sem um padrão de caracteres...
Nem mesmo APIs modernas existiriam.
No fim das contas...
Todo sistema continua dependendo de um "alfabeto".
A diferença é apenas qual deles.
Dicas para quem está começando no Mainframe
Nunca abra arquivos EBCDIC diretamente no Notepad.
Use ferramentas que suportem conversão.
Aprenda a diferença entre arquivo texto e arquivo binário.
Nem tudo pode ser convertido.
Campos COMP, COMP-3 e binários jamais devem ser tratados como texto.
Conheça sua Code Page.
CP037 não é igual à CP1047.
Esse detalhe salva horas de investigação.
Aprenda como funciona FTP ASCII e FTP Binary.
Uma configuração incorreta pode "corromper" um arquivo apenas durante a transferência.
Na verdade, o arquivo original continua íntegro.
Não tenha medo do EBCDIC.
Ele parece estranho apenas porque crescemos utilizando ASCII e UTF-8.
Depois de alguns dias convivendo com Mainframe ele se torna completamente natural.
O verdadeiro legado do EBCDIC
Existe uma frase famosa na engenharia:
"Se algo funciona perfeitamente há cinquenta anos, talvez exista uma boa razão para não mexer."
O EBCDIC sobreviveu não porque o mercado ficou parado.
Mas porque ele faz parte de uma arquitetura extremamente estável.
Enquanto tecnologias aparecem e desaparecem a cada cinco anos...
O IBM Z continua processando alguns dos sistemas mais críticos do planeta.
Não porque seja antigo.
Mas porque foi projetado para durar.
Um Café Antes de Ir...
O programador júnior normalmente olha para o EBCDIC e enxerga um problema.
O desenvolvedor experiente enxerga compatibilidade.
O arquiteto enxerga engenharia.
E o engenheiro de Mainframe enxerga algo ainda maior: uma decisão de projeto que atravessou gerações sem interromper negócios, preservando décadas de investimentos e garantindo que milhões de pessoas possam sacar dinheiro, comprar passagens, pagar contas e realizar transações todos os dias.
Da próxima vez que você abrir um arquivo EBCDIC e encontrar uma "sopa de caracteres", lembre-se: o arquivo não está errado. Apenas está falando a língua nativa de um dos ecossistemas computacionais mais robustos já construídos.
Porque, no fim das contas, o EBCDIC nunca foi um obstáculo ao futuro. Ele sempre foi a ponte silenciosa entre mais de 60 anos de história da computação e o IBM Z que continua sustentando o mundo digital de hoje.
E essa, meu colega Padawan, é uma das maiores lições que o Mainframe pode ensinar: boas arquiteturas envelhecem muito melhor do que modismos tecnológicos. ☕
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, DATA e PROCEDURE.”
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
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 2007
Esse 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.
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.
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-OPERACAO
O 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:
000012345
o COBOL poderá tratá-los como:
1.234,45
conforme 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.
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.
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-TREM
Igor 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-PERFORM
A 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-EVALUATE
O 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-EVALUATE
O 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-ENTRADA
o 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-EVALUATE
Os 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-REGISTRO
Sem 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 COMMIT está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.
EVALUATE WS-RESP
WHEN DFHRESP(NORMAL)
PERFORM PROCESSAR-CONTA
WHEN DFHRESP(NOTFND)
PERFORM TRATAR-CONTA-INEXISTENTE
WHEN OTHER
PERFORM TRATAR-ERRO-CICS
END-EVALUATE
Aqui, 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-EXEC
Depois:
EVALUATE SQLCODE
WHEN ZERO
PERFORM PROCESSAR-CONTA
WHEN +100
PERFORM TRATAR-NAO-ENCONTRADA
WHEN OTHER
PERFORM TRATAR-ERRO-DB2
END-EVALUATE
COBOL 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-TOTAL
a 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.
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:
S0C7 por dado decimal inválido;
S0C4 por referência indevida à memória;
S0CB por 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 SALDO
Mesmo que a regra correta fosse:
SUBTRACT TAXA FROM SALDO
Sintaticamente correto.
Financeiramente desastroso.
Clareza também não vem automaticamente
Compare:
IF X = 'S'
PERFORM 9000
END-IF
com:
IF CLIENTE-ELEGIVEL
PERFORM CALCULAR-LIMITE
END-IF
O 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.
IF CONDICAO
PERFORM ACAO
ELSE
PERFORM OUTRA-ACAO
END-IF
Use 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 TRUE
O vilão já entrou no programa.
21. O mapa mental definitivo
A versão simples é:
Definir dados → processar → obter resultado
A 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 retorno
COBOL 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 o FILE STATUS. Antes de atualizar o saldo, conheça o contrato. E, quando o Dr. Loveless oferecer um GO TO para uma rotina que ninguém encontra, peça primeiro o mapa do fluxo.
Vagner Renato Bellacosa trabalha com IBM Mainframe
desde 1988
,
é IBM Champion e especialista em COBOL, CICS, Db2,
z/OS e IBM Z. Compartilha experiências profissionais,
conhecimento técnico, história da computação e práticas
do universo mainframe para aproximar novas gerações das
tecnologias que sustentam empresas, bancos e governos
ao redor do mundo.
IBM Champion
IBM Z
COBOL
CICS
Db2
z/OS
Mainframe desde 1988