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

ILE: moduli, programmi e service program

Rivista il Verificata su IBM i 7.5

Accedi per salvare

Fino ai primi anni Novanta 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.

ILEIntegrated 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. È comodo, ed è il motivo per cui in giro si vedono tanti programmi ILE fatti di un modulo solo, che è ILE nella forma e OPM nella sostanza.

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, il valore di ritorno esiste, e il costo della chiamata è di un altro ordine di grandezza.

**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

Un service program ha una firma, calcolata dall'elenco delle procedure che esporta. I programmi che lo usano se la portano dentro, e al momento di partire il sistema verifica che coincida.

Avvertenza

aggiungere una procedura a un service program e ricompilarlo cambia la firma. Tutti i programmi legati a quel service program smettono di partire con un errore di firma, e vanno ricompilati tutti. Su un applicativo grande non è un pomeriggio: è un rilascio.

Si evita dichiarando le esportazioni con il binder language — un sorgente che elenca le procedure esportate e le tiene in un ordine stabile — e aggiungendo le nuove in coda senza toccare le vecchie. Fatto dal primo giorno costa dieci minuti; fatto dopo, si paga una volta con una ricompilazione generale e poi non più.

I gruppi di attivazione

Qui sta la parte che fa più danni, perché è invisibile finché non si manifesta.

Un gruppo di attivazione è lo spazio in cui vive un programma mentre gira: le sue variabili statiche, i file che ha aperto, il suo controllo di commit, la sua gestione degli errori. Si sceglie alla compilazione, e ci sono tre possibilità.

  • ACTGRP(*NEW) — ogni chiamata crea un gruppo nuovo, che viene distrutto al ritorno. Pulito, e costoso: i file vengono riaperti ogni volta.
  • ACTGRP(*CALLER) — il programma gira nel gruppo di chi lo ha chiamato. È la scelta giusta per un service program, che deve stare dove sta chi lo usa.
  • ACTGRP(NOME) — un gruppo con un nome deciso da noi, condiviso da tutto l'applicativo. È la scelta giusta per i programmi.

Avvertenza

un gruppo di attivazione non si chiude da solo quando il programma finisce. Se il programma ritorna senza *INLR acceso, restano vivi il gruppo, le variabili e i file aperti — che è utile quando lo si vuole, ed è una perdita di memoria quando non lo si sa. RCLACTGRP ACTGRP(NOME) chiude un gruppo chiamato per nome, ma su un job attivo va usato sapendo che cosa si sta buttando via.

Importante

il gruppo di attivazione decide anche l'ambito del controllo di commit. Due programmi in gruppi diversi hanno transazioni diverse, e un COMMIT in uno non chiude quello che ha fatto l'altro. Quando una transazione si conferma a metà, la causa è quasi sempre questa e quasi mai il codice del commit.

Un programma OPM, per finire, gira sempre nel gruppo di attivazione predefinito, che è quello del sistema e non si può reclamare. Mescolare OPM e ILE nella stessa catena di chiamate funziona, ed è normale in un applicativo vecchio, ma è il punto in cui il comportamento degli errori e delle transazioni smette di essere prevedibile.

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. Se la risposta è "ILE, un modulo solo, ACTGRP(*NEW)", si sta guardando codice OPM compilato con un compilatore nuovo — che funziona benissimo, e che non ha nessuno dei vantaggi per cui ILE è stato fatto.

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