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.
Commenti
Nessun commento ancora. Sii il primo a commentare!
Devi avere un account per commentare. Accedi · Registrati