Prima di ILE un programma era un blocco solo: un sorgente, una compilazione,
un oggetto *PGM che conteneva tutto. È il modello chiamato OPM, Original Program
Model, e su molti sistemi c'è ancora codice che ci gira dentro.
ILE (Integrated Language Environment) ha cambiato l'unità di lavoro. Non si compila più un programma: si compilano moduli, e i moduli si legano insieme a formare un programma o un service program.
I tre oggetti
- Modulo (
*MODULE): il risultato di una compilazione. Non si esegue: è un mattone. - Programma (
*PGM): uno o più moduli legati insieme, con un punto d'ingresso. Questo si chiama. - Service program (
*SRVPGM): uno o più moduli che espongono procedure agli altri, e che non si chiama direttamente. È l'equivalente di una libreria condivisa.
CRTRPGMOD MODULE(PRODLIB/CALCOLI) SRCFILE(PRODLIB/QRPGLESRC)
CRTPGM PGM(PRODLIB/FATTURE) MODULE(PRODLIB/FATTURE PRODLIB/CALCOLI)
CRTSRVPGM SRVPGM(PRODLIB/UTILITA) MODULE(PRODLIB/UTILITA) EXPORT(*ALL)
CRTBNDRPG fa le due cose in una sola mossa: compila il modulo e lo lega subito in un
programma. Di serie lo fa con DFTACTGRP(*YES): il programma gira sempre nel gruppo di
attivazione predefinito, come un programma OPM, e il collegamento statico non è
disponibile, quindi niente BNDDIR, niente ACTGRP, e ogni chiamata nel sorgente deve
chiamare un programma, non una procedura. IBM lo presenta come il modo di portare in ILE
RPG un programma alla volta. Per usare service program e gruppi di attivazione serve
DFTACTGRP(*NO).
Perché conviene separare
La differenza si vede quando una funzione serve a venti programmi.
Nel modello vecchio la si scriveva in un programma a parte e la si richiamava con CALL.
Funziona, ma una CALL è dinamica: costa a ogni chiamata, i parametri non sono controllati
dal compilatore, e non si può restituire un valore, solo modificare i parametri.
Con ILE la si scrive come procedura dentro un service program, e la si chiama come una funzione qualsiasi. Il collegamento è statico: il compilatore controlla il numero e il tipo dei parametri, e il valore di ritorno esiste.
**FREE
dcl-pr calcolaImponibile packed(11:2) extproc('CALCOLA_IMPONIBILE');
importo packed(11:2) const;
aliquota packed(5:2) const;
end-pr;
imponibile = calcolaImponibile(totale: 22);
Consiglio
è la modernizzazione con il miglior rapporto fra risultato e rischio. Non tocca il codice esistente, non cambia i dati, non richiede una riscrittura: si estrae in una procedura la logica che oggi è copiata in dieci programmi, e da quel momento si corregge in un posto solo. Il capitolo sulla modernizzazione riprende da qui.
La directory di binding
Elencare a mano i moduli e i service program a ogni compilazione diventa presto
ingestibile. Una directory di binding (*BNDDIR) è un elenco: si dichiara una volta e
il compilatore ci pesca quello che serve.
CRTBNDDIR BNDDIR(PRODLIB/APPBND)
ADDBNDDIRE BNDDIR(PRODLIB/APPBND) OBJ((PRODLIB/UTILITA *SRVPGM))
Nel sorgente si dichiara una volta sola:
ctl-opt bnddir('PRODLIB/APPBND');
La firma
L'interfaccia pubblica di un service program, cioè le procedure e i dati che esporta, è rappresentata da una firma. Se non la si dichiara, il binder la calcola dai nomi esportati e dal loro ordine. I programmi legati al service program la conservano, e il sistema la confronta quando li attiva.
Avvertenza
con EXPORT(*ALL) e nessun sorgente di binder, aggiungere una procedura
cambia l'elenco e quindi la firma, e i programmi già legati non la ritrovano più. IBM
avverte che un cambiamento incompatibile può far smettere di funzionare correttamente i
programmi che restano legati alla versione vecchia.
Si evita con il binder language: un sorgente con STRPGMEXP, EXPORT ed ENDPGMEXP.
Le regole IBM: i nomi esistenti non si tolgono e non si riordinano, i nuovi vanno in
fondo; senza una firma esplicita, a ogni aggiunta serve un nuovo blocco
STRPGMEXP PGMLVL(*CURRENT), e quello di prima resta come PGMLVL(*PRV), così i programmi
legati alla firma vecchia continuano a partire. RTVBNDSRC genera il sorgente dagli
export di un modulo o di un service program esistente.
STRPGMEXP PGMLVL(*CURRENT)
EXPORT SYMBOL('CALCOLA_IMPONIBILE')
EXPORT SYMBOL('CALCOLA_IVA')
ENDPGMEXP
STRPGMEXP PGMLVL(*PRV)
EXPORT SYMBOL('CALCOLA_IMPONIBILE')
ENDPGMEXP
Per sostituire un modulo in un programma o in un service program già creato, senza
rifarlo da capo, ci sono UPDPGM e UPDSRVPGM. Un job che ha già attivato la versione
vecchia continua a usarla; le attivazioni nuove usano quella aggiornata.
I gruppi di attivazione
Un gruppo di attivazione è lo spazio in cui vive un programma ILE mentre gira: le sue
variabili statiche, i file che ha aperto, il suo controllo di commit. Non c'è un comando
per crearne uno: lo decide l'attributo ACTGRP dato a CRTPGM o CRTSRVPGM.
| Valore | Che cosa succede |
|---|---|
ACTGRP(nome) |
un gruppo con un nome deciso da noi, creato la prima volta che serve e usato da tutti i programmi e service program con lo stesso nome |
ACTGRP(*NEW) |
un gruppo nuovo, con un nome scelto dal sistema, a ogni chiamata. Non vale per i service program |
ACTGRP(*CALLER) |
il gruppo di chi chiama; non se ne crea mai uno nuovo |
ACTGRP(*ENTMOD) |
il sistema guarda il modulo d'ingresso e sceglie secondo il linguaggio |
Avvertenza
un gruppo con nome non si chiude quando il programma ritorna: un
ritorno normale, anche con un RETURN di RPG, lo lascia nel job per riusarlo, con le sue
variabili e i suoi file aperti. Un gruppo *NEW, invece, si cancella al ritorno, perché
nessuno potrebbe riusarlo. Un gruppo con nome si chiude con RCLACTGRP, solo se nessun
programma attivo lo sta usando, oppure finisce con il job.
Importante
il controllo di commit si definisce di solito a livello di gruppo di
attivazione o di job (STRCMTCTL, CMTSCOPE). Con una definizione a livello di gruppo,
due programmi in gruppi diversi hanno transazioni diverse, e un COMMIT in uno non
conferma quello che ha fatto l'altro.
I programmi OPM girano nei gruppi di attivazione predefiniti, due, che il sistema crea
all'avvio del job e cancella alla sua fine; non si possono cancellare prima. Un programma
ILE ci finisce se è creato con ACTGRP(*CALLER) ed è chiamato da lì, oppure con
DFTACTGRP(*YES).
Che cosa guardare in un applicativo che si eredita
DSPPGM PGM(PRODLIB/FATTURE) DETAIL(*MODULE)
DSPSRVPGM SRVPGM(PRODLIB/UTILITA) DETAIL(*PROCEXP)
Tre domande dicono quasi tutto: i programmi sono ILE o OPM, sono fatti di un modulo solo o
di più, e in quale gruppo di attivazione girano. Un programma RPG creato con CRTBNDRPG e
le impostazioni di serie gira nel gruppo predefinito come un OPM, e non può legarsi a un
service program.
Commenti
Nessun commento ancora. Sii il primo a commentare!
Devi avere un account per commentare. Accedi · Registrati