Programmare su IBM i: sorgenti, ILE, RPG e SQL Capitolo 3 di 9

RPG: dalle colonne al free-form

Rivista il Verificata su IBM i 7.5

Accedi per salvare

Un sorgente RPG di trent'anni fa sembra illeggibile perché la posizione di un carattere conta. Ogni riga comincia con una lettera che ne dichiara il tipo, e ogni informazione ha la sua colonna: la funzione della riga si legge da dove stanno le cose, non da come sono scritte.

Non era una stranezza: era il modo di scrivere codice quando l'unità di input era una scheda perforata da ottanta colonne, e ogni carattere sprecato era spazio tolto ai dati.

Le specifiche

Il tipo di riga si dichiara in colonna 6, e le lettere si incontrano ancora oggi leggendo codice storico:

Lettera Che cosa dichiara
H opzioni di compilazione del programma
F i file usati
D variabili, strutture, costanti, prototipi
I come sono fatti i record in ingresso
C le istruzioni
O come sono fatti i record in uscita
P inizio e fine di una procedura

Le specifiche I e O oggi si vedono raramente: descrivevano a mano il tracciato dei record, cosa che il compilatore ricava da solo dalla descrizione esterna del file.

Che cosa è cambiato

Il free-form non è arrivato tutto insieme, e questo spiega perché in giro si trovano tre forme diverse dello stesso linguaggio.

Prima sono diventate libere le istruzioni, con /FREE e /END-FREE a delimitare i blocchi: il calcolo si scriveva liberamente, ma file e variabili restavano a colonne. È la forma di transizione, e su molti sistemi è quella prevalente.

Poi è diventato libero tutto. Con **FREE sulla prima riga, il sorgente non ha più colonne da rispettare: ctl-opt al posto della specifica H, dcl-f per i file, dcl-ds e dcl-s per i dati, dcl-proc per le procedure.

**FREE
ctl-opt dftactgrp(*no) actgrp('FATTURE') option(*srcstmt: *nodebugio);

dcl-f ordini disk keyed usage(*input);

dcl-s totale packed(11:2);
dcl-s aliquota packed(5:2) inz(22);

dcl-ds cliente qualified;
  codice char(10);
  nome char(50);
  saldo packed(11:2);
end-ds;

dcl-proc calcolaImponibile;
  dcl-pi *n packed(11:2);
    importo packed(11:2) const;
    perc packed(5:2) const;
  end-pi;

  return importo - (importo * perc / 100);
end-proc;

Nota

il free-form completo è arrivato con il rilascio 7.1 attraverso un aggiornamento tecnologico, ed è pieno da 7.2 in avanti. Su un sistema fermo a un rilascio anteriore, o aggiornato ma senza le PTF di quel periodo, **FREE non compila. È il primo controllo da fare prima di proporre a un reparto di cambiare stile.

Che cosa non è cambiato

Il free-form ha cambiato come si scrive, non che cosa fa il linguaggio. Il ciclo RPG, gli indicatori, i livelli di rottura, la lettura a record: sono tutti ancora lì, e un programma scritto in free-form può usarli esattamente come prima.

Questo è importante perché smonta un equivoco frequente in due direzioni. Convertire un programma in free-form non lo modernizza: lo rende leggibile. E un programma vecchio ma scritto bene non diventa migliore perché lo si riscrive con la sintassi nuova — diventa un programma da riprovare da capo, con lo stesso comportamento di prima e un rischio in più.

Consiglio

la conversione ha senso quando si sta comunque mettendo le mani in un programma, non come progetto a sé. Un programma che nessuno tocca da dieci anni e che funziona è l'ultimo candidato: il beneficio è nullo finché nessuno lo legge, e il rischio è reale.

Per la conversione automatica esiste uno strumento sul sito, utile per farsi un'idea di come verrebbe un sorgente prima di decidere:

Le cose che oggi si scrivono diversamente

Tre abitudini distinguono un programma scritto di recente da uno di vent'anni fa, e sono tutte adottabili gradualmente.

Le variabili si dichiarano dove servono. Nel modello vecchio tutte le variabili stavano insieme in cima. In free-form una dichiarazione può stare dentro una procedura, il che significa che una variabile ha un ambito, e che due procedure non possono pestarsi i piedi per sbaglio.

Gli indicatori si usano meno. *IN71 acceso da qualche parte e letto trecento righe dopo è il motivo per cui un programma RPG diventa incomprensibile. Le condizioni oggi si scrivono con variabili con un nome, e gli indicatori restano dove il linguaggio li impone — i file video, per esempio.

Le funzioni predefinite hanno sostituito le istruzioni. %scan, %subst, %trim, %date, %diff, %editc fanno con una riga quello che prima richiedeva istruzioni dedicate e variabili di appoggio.

Il ciclo RPG

Merita un paragrafo perché è la cosa che sorprende di più chi arriva da altri linguaggi.

L'RPG classico non ha un main che si legge dall'alto in basso: ha un ciclo implicito, che legge un record dal file primario, esegue i calcoli, scrive l'output, e ricomincia finché il file non finisce. Il programma descrive che cosa fare a ogni record; a chiamarlo è il linguaggio.

Sul codice storico questo va conosciuto per leggerlo. Sul codice nuovo non si usa più: si dichiara dcl-f senza file primario e si scrive un ciclo esplicito, che chiunque può seguire.

Avvertenza

in un programma con il ciclo attivo, l'indicatore *INLR non è un dettaglio. Acceso, chiude i file e ripulisce alla fine; spento, il programma "ritorna" lasciando tutto aperto e le variabili con il valore che avevano — e alla chiamata successiva riparte da lì. Metà dei comportamenti inspiegabili in RPG si spiegano con *INLR non acceso e un gruppo di attivazione condiviso.

Torna all'indice della guida

← Torna al blog

Commenti

Nessun commento ancora. Sii il primo a commentare!

Devi avere un account per commentare. Accedi · Registrati