| Bellacosa Mainframe crie sua propria função intrinseca no Cobol Mainframe |
☕ Um Café no Bellacosa Mainframe
Criando Sua Própria Função Intrínseca no COBOL
O Guia do Programador COBOL Padawan para Expandir os Poderes da Linguagem com a Ajuda do Capitão Kirk
"O universo não se expande porque alguém pediu permissão. Ele se expande porque alguém teve coragem de explorar o desconhecido."
— Capitão James T. Kirk (adaptado para Bellacosa Mainframe)
Introdução — "Mas... eu posso criar uma nova FUNCTION no COBOL?"
Essa é uma das perguntas que quase nenhum curso responde.
Durante décadas, programadores COBOL aprenderam algo parecido com isto:
FUNCTION CURRENT-DATE
FUNCTION UPPER-CASE
FUNCTION LOWER-CASE
FUNCTION LENGTH
FUNCTION RANDOM
E a conclusão natural era:
"Essas funções fazem parte da linguagem. Não posso criar outras."
Durante muitos anos isso realmente era verdade.
Mas a IBM resolveu mudar isso.
Hoje, no Enterprise COBOL moderno, você pode criar suas próprias funções, reutilizáveis exatamente como uma FUNCTION nativa da linguagem.
É quase como ensinar novos truques ao compilador.
Se você já trabalhou com:
Java (methods)
C (functions)
Python (def)
C# (methods)
vai perceber que finalmente o COBOL ganhou algo semelhante.
E a melhor parte?
Isso continua extremamente eficiente para ambientes bancários.
Hoje vamos descobrir como.
E, como sempre, o Capitão Kirk nos acompanhará nessa missão.
A ponte da Enterprise
Imagine a USS Enterprise.
Cada oficial possui uma especialidade.
Spock calcula.
Scotty cuida do motor.
McCoy resolve problemas médicos.
Kirk apenas chama quem precisa.
Ele não faz tudo.
Ele reutiliza especialistas.
Uma User-Defined Function faz exatamente isso.
Você cria um especialista.
Depois qualquer programa COBOL pode chamá-lo.
Antes disso...
Durante mais de 50 anos havia apenas dois caminhos.
Opção 1
Escrever código repetido.
CALCULA-JUROS.
CALCULA-DESCONTO.
CALCULA-IDADE.
Copiado dezenas de vezes.
Opção 2
Criar um subprograma
CALL "JUROS"
Funciona.
Mas possui custo.
Existe:
parameter list
linkage
transferência de controle
convenções de chamada
Embora eficiente, ainda existe overhead.
As User Defined Functions diminuem bastante esse problema.
O que é uma User-Defined Function?
É uma função escrita pelo próprio programador.
Ela recebe parâmetros.
Executa lógica.
Retorna um único valor.
Exemplo imaginário:
FUNCTION CALCULA-CPF()
ou
FUNCTION REMOVE-ESPACOS()
ou
FUNCTION SOMA-IMPOSTOS()
Ela parece uma função da linguagem.
Mas foi você quem escreveu.
Desde quando isso existe?
No mundo IBM Mainframe, o suporte chegou com o IBM Enterprise COBOL 5 (introduzido em 2013), quando a linguagem passou a incorporar recursos modernos alinhados aos padrões mais recentes do COBOL. As capacidades foram ampliadas e refinadas nas versões 6.1, 6.2, 6.3, 6.4 e 6.5, que hoje são as mais encontradas em ambientes z/OS corporativos.
Na prática, é nas versões Enterprise COBOL 5.x e, principalmente, 6.x que esse recurso se tornou realmente utilizável em projetos modernos.
Precisa instalar alguma coisa?
Boa notícia.
Não.
Nada.
Se o compilador suporta User-Defined Functions, elas já fazem parte do compilador.
Você apenas compila normalmente.
Não existe:
DLL
Plugin
Biblioteca externa
Como funciona?
A arquitetura é simples.
Programa A
↓
FUNCTION MINHA-FUNCTION()
↓
User Defined Function
↓
Retorna resultado
Muito parecido com isto:
resultado =
FUNCTION JUROS(valor)
Estrutura geral
Ela lembra um programa COBOL.
IDENTIFICATION DIVISION
FUNCTION-ID.
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.
END FUNCTION.
Observe algo curioso.
Não usamos
PROGRAM-ID
Usamos
FUNCTION-ID
Esse é o detalhe que transforma um programa em uma função.
Exemplo 1
Dobrando um número
IDENTIFICATION DIVISION.
FUNCTION-ID. DOBRO.
DATA DIVISION.
LINKAGE SECTION.
01 L-VALOR PIC S9(9) COMP-5.
01 L-RETORNO PIC S9(9) COMP-5.
PROCEDURE DIVISION USING L-VALOR
RETURNING L-RETORNO.
COMPUTE L-RETORNO = L-VALOR * 2
GOBACK.
END FUNCTION DOBRO.
Bonito.
Limpo.
Pequeno.
Agora o programa principal.
DISPLAY FUNCTION DOBRO(15)
Saída
30
Muito elegante.
Exemplo 2
Maior entre dois números
FUNCTION MAIOR(A,B)
Dentro:
IF A > B
MOVE A TO RETORNO
ELSE
MOVE B TO RETORNO
END-IF
Depois:
DISPLAY FUNCTION MAIOR(25 19)
Resultado
25
Exemplo 3
Calcular idade
FUNCTION IDADE(DATA-NASCIMENTO)
Internamente:
CURRENT-DATE
Subtrai
Retorna idade.
Depois:
DISPLAY FUNCTION IDADE(19980412)
Muito mais legível.
Onde declarar parâmetros?
Na
LINKAGE SECTION
Exemplo
01 PARAM1.
01 PARAM2.
Depois
PROCEDURE DIVISION USING
PARAM1
PARAM2
RETURNING RESULTADO
Muito parecido com um subprograma.
Como chamar?
COMPUTE WS-TOTAL =
FUNCTION JUROS(1000 15)
Ou
MOVE FUNCTION DOBRO(5)
TO WS-VALOR
Ou
DISPLAY FUNCTION TEXTO()
Posso chamar outras FUNCTIONS?
Sim.
Inclusive funções intrínsecas.
FUNCTION UPPER-CASE()
Dentro da sua função.
Exemplo
FUNCTION UPPER-CASE(cliente)
Retorna
JOÃO
Posso chamar um CALL?
Também.
CALL "ROTINA"
Nada impede.
Mas cuidado.
Funções devem ser pequenas.
O Capitão Kirk explica
Imagine que Kirk pede um café.
Ele não desmonta o replicador.
Ele apenas diz:
CAFÉ()
O replicador faz todo o trabalho.
Isso é encapsulamento.
Performance
Excelente.
Muito melhor do que copiar código.
Muito melhor para manutenção.
Além disso:
✔ reutilização
✔ cache de instruções
✔ otimização do compilador
✔ menor duplicação
Um detalhe importante
Funções devem retornar UM único valor.
Não dez.
Se precisa retornar muitas estruturas:
Use
CALL
Não FUNCTION.
Posso acessar arquivos VSAM?
Tecnicamente pode.
Mas...
Não deveria.
Funções devem ser previsíveis.
Boa função:
CALCULA
Ruim:
ABRE VSAM
FAZ I/O
ATUALIZA DB2
ENVIA MQ
O perigo dos efeitos colaterais
Imagine:
FUNCTION SALDO()
Você espera apenas consultar.
Mas internamente:
UPDATE DB2
Isso é perigoso.
Uma função deve produzir sempre o mesmo resultado para a mesma entrada, sempre que possível.
Erros comuns
1 Repetir lógica
Ao invés de:
FUNCTION IMPOSTO()
o programador copia:
COMPUTE...
100 vezes.
2 Fazer função enorme
Ruim
900 linhas
Boa
20
40
60 linhas
3 Muitos parâmetros
FUNCTION CALCULA(
A
B
C
D
E
F
G
H)
Já virou um monstro.
4 Fazer I/O
Evite.
5 Alterar estado global
Funções devem ser independentes.
Truques interessantes
Criar biblioteca matemática
FUNCTION MEDIA()
FUNCTION DESVIO()
FUNCTION MEDIANA()
Biblioteca financeira
JUROS
IOF
IR
TAXA
Biblioteca bancária
VALIDA-CPF
VALIDA-CNPJ
MOD11
DIGITO
Biblioteca texto
REMOVE-ESPACOS
NORMALIZA
CAPITALIZA
Organização recomendada
COPYBOOKS
FUNCTIONS
SUBPROGRAMAS
PROGRAMAS
Cada função em seu próprio membro.
Muito semelhante à organização de uma biblioteca reutilizável.
Boas práticas
✔ Nomeie funções de forma descritiva (CALCULA-JUROS, VALIDA-CPF, NORMALIZA-NOME).
✔ Mantenha apenas uma responsabilidade por função.
✔ Evite acessar arquivos, filas MQ ou banco de dados dentro de funções de cálculo.
✔ Prefira funções determinísticas: mesma entrada, mesma saída.
✔ Documente parâmetros e tipo de retorno.
✔ Teste cada função de forma isolada antes de utilizá-la em produção.
✔ Centralize funções reutilizáveis em bibliotecas compartilhadas pela equipe.
✔ Utilize compilação otimizada nas versões atuais do Enterprise COBOL para aproveitar as melhorias do compilador.
Quando usar FUNCTION e quando usar CALL?
| Situação | FUNCTION | CALL |
|---|---|---|
| Cálculos rápidos | ✅ Excelente | ✔ Possível |
| Manipulação de texto | ✅ Excelente | ✔ Possível |
| Validação de CPF/CNPJ | ✅ Ideal | ✔ Possível |
| Retornar um único valor | ✅ Melhor escolha | ✔ Possível |
| Atualizar Db2 | ❌ Evite | ✅ Recomendado |
| Processar VSAM | ❌ Evite | ✅ Recomendado |
| Enviar mensagens MQ | ❌ Evite | ✅ Recomendado |
| Processamento complexo com vários retornos | ❌ Não indicado | ✅ Ideal |
Um exemplo prático: função para calcular desconto
Imagine uma empresa que aplica um desconto de 10% sobre qualquer valor informado. Em vez de repetir o cálculo em dezenas de programas, criamos uma função reutilizável.
Função
IDENTIFICATION DIVISION.
FUNCTION-ID. CALC-DESCONTO.
DATA DIVISION.
LINKAGE SECTION.
01 LK-VALOR PIC S9(7)V99 COMP-3.
01 LK-RETORNO PIC S9(7)V99 COMP-3.
PROCEDURE DIVISION
USING LK-VALOR
RETURNING LK-RETORNO.
COMPUTE LK-RETORNO =
LK-VALOR * 0.90
GOBACK.
END FUNCTION CALC-DESCONTO.
Programa chamador
IDENTIFICATION DIVISION.
PROGRAM-ID. TESTE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-VALOR PIC S9(7)V99 VALUE 1000.
01 WS-FINAL PIC S9(7)V99.
PROCEDURE DIVISION.
MOVE FUNCTION CALC-DESCONTO(WS-VALOR)
TO WS-FINAL
DISPLAY "Valor original : " WS-VALOR
DISPLAY "Valor final : " WS-FINAL
STOP RUN.
Saída esperada:
Valor original : 1000.00
Valor final : 900.00
Perceba como o programa principal permanece limpo. Toda a regra de negócio fica encapsulada em um único lugar. Se amanhã o desconto passar para 12%, basta recompilar a função.
A visão do Capitão Kirk
No final da missão, Kirk reúne sua tripulação na ponte da Enterprise.
Spock observa:
"Capitão, seria lógico repetir o mesmo algoritmo em 147 programas?"
Kirk sorri.
"Claro que não, Spock. Criamos uma função, compartilhamos conhecimento e seguimos explorando."
Scotty complementa:
"Quanto menos motores improvisados, menos explosões na sala de máquinas."
McCoy, olhando para um enorme programa COBOL cheio de código duplicado, comenta:
"Ele está vivo... mas não por muito tempo."
Essa é a verdadeira filosofia das User-Defined Functions: transformar conhecimento reutilizável em componentes pequenos, claros e confiáveis.
Cuidados e atenção
Como compilar e ajustar sua função intrinseca no Cobol 6.4
https://eljefemidnightlunch.blogspot.com/2022/07/alerta-vermelho-na-enterprise.html
O que são Funções Intrincsecas no Cobol
https://eljefemidnightlunch.blogspot.com/2022/09/funcoes-intrinsecas-no-enterprise-cobol.html
Conclusão — Seu próximo passo como Padawan COBOL
As User-Defined Functions representam uma das evoluções mais elegantes do COBOL moderno. Elas aproximam a linguagem das práticas de engenharia de software utilizadas em linguagens contemporâneas, sem abrir mão da robustez que tornou o COBOL o alicerce de bancos, seguradoras e grandes empresas por décadas.
Para um Padawan COBOL, dominar esse recurso significa deixar de escrever programas monolíticos e começar a construir bibliotecas reutilizáveis de regras de negócio. Isso reduz duplicação de código, facilita testes, melhora a manutenção e torna o desenvolvimento muito mais organizado.
No universo Bellacosa Mainframe, criar uma nova função é como adicionar um novo oficial especializado à tripulação da USS Enterprise. Cada função tem uma missão específica, executa seu trabalho com excelência e permite que o programa principal permaneça simples, elegante e focado em coordenar a missão.
Porque, no fim das contas, os melhores sistemas corporativos não são aqueles que possuem mais linhas de código, mas aqueles em que cada componente conhece exatamente seu papel — assim como cada oficial da Frota Estelar conhece sua estação na ponte de comando.
Sem comentários:
Enviar um comentário