\articolo{EUNice: Un ambiente integrato per la programmazione
object-oriented in E}{Vincenzo Gervasi}

\paragrafo{Introduzione}
\noindent Avviene talvolta, per qualche strana combinazione di eventi, che un piccolo
numero di persone, trovandosi in un ambiente favorevole, possa conseguire
grandi progressi, destinati a lasciare il segno, ma i cui effetti non sono
visibili immediatamente. È accaduto per i fisici di via Panisperna, non è
accaduto alla Microsoft, ed è invece proprio ciò che è successo al PARC, il
mitico ``Palo Alto Research Center'' della Xerox, intorno alla fine degli anni
'70.

In quella vera e propria fucina di idee sono nati, infatti, il mouse e le
interfacce utente grafiche, nonché il primo linguaggio object-oriented
realmente utile: Smalltalk. Oggi che le GUI hanno quasi portato
all'estinzione le vecchie interfacce utente ``a linea di comando'', e il
paradigma ``a oggetti'' è divenuto patrimonio comune di ogni buon
programmatore, assistiamo a un continuo fiorire di compilatori per
linguaggi object-oriented, in particolar modo per il C++, e tutti offrono
sofisticati strumenti di programmazione visuale, ambienti integrati,
debugging remoto tramite Internet e quant'altro. Tutti? Beh, a questo punto
l'utente \A si sente un po' trascurato. È vero che esistono eccellenti
compilatori per vari linguaggi object oriented, ma quasi nessuno va oltre le
(scarse) grazie di \c{ReadArgs()} quanto a interfaccia utente. Il
progetto EUNice, oggetto di questo intervento, intende fare un piccolo passo
avanti in questa direzione.

\paragrafo{I vantaggi della OOP}
\noindent Se ben sfruttata, la programmazione object-oriented ha molto da offrire al
programmatore. In primo luogo, risulta aumentata la riusabilità del codice;
è infatti possibile (e conveniente) che oggetti già sviluppati e ben testati
entrino a far parte di nuove applicazioni, come rilevato, fra gli altri, in
[1]. Ne guadagna anche la strutturazione del sorgente: gli oggetti, infatti,
definiscono implicitamente dei confini ``naturali'' per i moduli costituenti
un'applicazione, e favoriscono la corretta definizione delle relative
interfacce e della documentazione associata.

Entrambe queste caratteristiche derivano dalla capacità degli oggetti di
incapsulare al loro interno tutta l'informazione (sia sotto forma di dati
che di algoritmi) necessaria per l'implementazione del comportamento
desiderato, lasciando visibile all'esterno soltanto la definizione
dell'oggetto stesso (principalmente sotto forma di metodi che possono essere
invocati su di esso).

Un'altra importantissima caratteristica degli oggetti è la possibilità di
costruire su quanto già esistente, specializzando il comportamento di un
oggetto, attraverso il meccanismo dell'ereditarietà. La proprietà duale
rispetto alla specializzazione è, naturalmente, la generalizzazione; la
possibilità di generalizzare comportamenti, attraverso la creazione di
classi ``genitori'' comuni per oggetti diversi, costituisce un'utile
opportunità per evitare ridondanze (ciò, a sua volta, fa diminuire i tempi
di sviluppo e di testing, nonché la dimensione dell'applicazione finale).
Per essere maggiormente efficaci, queste caratteristiche dovrebbero essere
sfruttate sin dalla fase di analisi, e poi ``traghettate'' verso il progetto
e la codifica; poiché ciascuna di queste fasi può aggiungere ulteriori
oggetti, capita sovente di dover gestire un numero molto grande di oggetti,
classi, relazioni di ereditarietà, di contenimento e quant'altro. Da qui la
necessità di avere a disposizione durante lo sviluppo strumenti adeguati
per la gestione di queste problematiche, strumenti che durante la
fase di analisi e progetto prendono la forma di metodi di lavoro, come
l'Object Oriented Analysis (OOA), dotati di opportune notazioni;
un'eccellente introduzione a queste tematiche è offerta da [2], mentre come
testo di riferimento ci si può rivolgere a [3]. Durante la fase di codifica,
tuttavia, occorre che questi strumenti siano strettamente connessi con
l'ambiente in cui opera il programmatore, e assumano quindi la forma di tool
integrati all'ambiente di sviluppo tradizionale (per una breve trattazione
dei vantaggi e svantaggi degli ambienti di sviluppo orientati al linguaggio,
si veda [9]).



\paragrafo{La OOP in E}
\noindent Il linguaggio E di Wouter van Oortmerssen, descritto in [4], fornisce molte
delle caratteristiche usualmente presenti nei linguaggi object-oriented.
L'implementazione di tali caratteristiche passa attraverso il concetto degli
\c{OBJECT}, che corrispondono ai \c{record} del Pascal o alle \c{struct} del C, e assumono la seguente forma sintattica:

\begin{codestyle}
OBJECT <nome>
   ...
   <dichiarazione dei campi>
   ...
ENDOBJECT
\end{codestyle}

\noindent In seguito a questa dichiarazione, \c{<nome>} diventa un tipo del linguaggio,
che è possibile istanziare tramite la (successiva) dichiarazione

\begin{codestyle}
DEF <nome var>:<nome obj>
\end{codestyle}

\noindent La terminologia impiegata da E può essere fuorviante, in quanto la
dichiarazione \c{OBJECT} crea quella che in altri linguaggi è chiamata classe,
mentre la \c{DEF} (che, in E, è detta definizione di variabile) crea un'istanza
della classe, cioè un oggetto.

Il data hiding, ovvero l'incapsulamento, è affidato ai due specificatori
\c{PRIVATE} e \c{PUBLIC}, che fanno sì che i dati successivi siano visibili
all'esterno dell'oggetto (\c{PUBLIC}) o soltanto ai suoi metodi (\c{PRIVATE});
l'ulteriore specificatore \c{EXPORT}, preposto alla dichiarazione dell'OBJECT,
fa sì che l'oggetto sia visibile al di fuori del modulo in cui è definito.

La definizione dei metodi segue le regole normali per la definizione di
procedure in E, con l'aggiunta della clausola \c{OF <nome obj>}, come in

\begin{codestyle}
PROC <nome proc>(<par. formali>)
                       OF <nome obj>
   ...
   <codice>
   ...
ENDPROC
\end{codestyle}

\noindent L'unica particolarità dei metodi rispetto alle normali procedure è che,
all'interno del \c{<codice>}, la variabile speciale \c{self} punta all'istanza a cui
il metodo in esecuzione appartiene, e lo specificatore \c{SUPER}, preposto ad
una chiamata di metodo, permette di accedere ai metodi della classe
genitrice (la super-classe) piuttosto che ai propri.

Dopo tutto ciò, è possibile invocare il metodo con la classica notazione del
``punto'', come per i campi di dati:

\begin{codestyle}
<nome var>.<nome proc>(<par. attuali>)
\end{codestyle}

\noindent Infine, l'ereditarietà si ottiene semplicemente aggiungendo la clausola \c{OF
<genitore>} alla dichiarazione dell'\c{OBJECT}, come in

\begin{codestyle}
OBJECT <figlio> OF <genitore>
   ...
ENDOBJECT
\end{codestyle}

\noindent Naturalmente, in questo modo si ereditano tutti i dati e i metodi di
\c{<genitore>}, ed è possibile ridefinirli o aggiungerne altri secondo i canoni
della OOP. Purtroppo, almeno nella versione attuale di E non è implementata
l'ereditarietà multipla (questa è una scelta di progetto, come vedremo fra
breve).

L'ultima caratteristica che è usualmente associata alla OOP, e che il
linguaggio E non offre direttamente, è il cosiddetto polimorfismo, ovvero la
possibilità di eseguire la stessa operazione su oggetti diversi. \A E
affronta il problema a due livelli: in primo luogo offrendo un polimorfismo
a basso livello, consistente nel fatto che tutti i tipi di dato del
linguaggio (e definiti dal programmatore) sono rappresentati come \c{LONG}
a 32 bit (è quindi possibile gestire liste, insiemi ecc.~di dati generici);
il secondo meccanismo è quello del typing dinamico (in una accezione
ristretta) per cui, in seguito all'invocazione di un metodo, viene eseguito
il metodo associato al tipo reale di un \c{OBJECT} (che potrebbe essere,
per esempio, un parametro passato e una procedura), e non quello associato
alla sua dichiarazione (che potrebbe riferirsi a uno qualunque dei suoi
genitori). I costrutti che abbiamo qui esposto brevemente coprono tutta la
OOP in E, e sono sufficienti per i nostri scopi; per maggiori dettagli,
oltre al già citato [4], si può vedere [5] o, in lingua italiana, [6].



\paragrafo{Problemi con la OOP in E}
\noindent Questo approccio alla programmazione object-oriented non è privo di
svantaggi: alcuni derivano da precise scelte dell'autore del linguaggio
(l'assenza di ereditarietà multipla, per esempio, è necessaria per mantenere
la compatibilità strutturale fra oggetti che siano fra loro in relazione di
ereditarietà, ovvero la sovrapponibilità delle rispettive rappresentazioni
in memoria), altri dalla necessaria integrazione delle caratteristiche
object-oriented di E con il resto del linguaggio (non è possibile, per
esempio, effettuare l'overloading di procedure e operatori perché il
linguaggio ha una struttura dei tipi molto ``morbida'', riconducendo tutto
alla \c{LONG} a 32 bit). Questo, unitamente al fatto che E non è un
linguaggio ``sicuro'' (come, d'altronde, non lo sono C e C++) e che è
responsabilità del programmatore assicurare che il suo applicativo non causi
crash, dovuti per esempio, all'uso errato dei puntatori, rende
particolarmente importante l'appropriata documentazione degli oggetti e dei
relativi metodi, e allo stesso modo rende indispensabile una certa
disciplina da parte del programmatore.

Il problema maggiore che ci si trova ad affrontare, comunque, è quello
relativo alla complessità della rappresentazione dell'applicativo. In E,
infatti, l'unità di programmazione object-oriented è l'\c{OBJECT}, mentre
quella di data-hiding (il package, per usare la terminologia Ada) è il
modulo, che coincide con un file sorgente. Questa scelta, per molti versi
del tutto condivisibile, ha come effetto collaterale il proliferare di file
sorgente qualora il programmatore scelga un approccio di data-hiding
completo (la cosiddetta programmazione a black-box), com'è spesso il caso
(in questo modo si assicura la massima modularità e riusabilità del codice).
La programmazione si trasforma allora in una continua consultazione di altri
moduli, alla ricerca del corretto nome del tal metodo, o del tipo dei
parametri di tal'altro, fra aperture e chiusure di finestre di editing (col
rischio di prendere pericolosi colpi d'aria). Inutile dire che questo modo
di procedere spezzetta il flusso mentale del programmatore, che quindi non
può concentrarsi esclusivamente sul particolare compito che sta affrontando,
distratto da minuzie come ``sarà \c{obf.reParseFile()} o \c{obF.reparseFile()}?''.



\paragrafo{EUNice: un tool per la OOP in E}
\noindent Esposte dunque le principali problematiche relative alla programmazione
object-oriented in generale, e a quella tramite il linguaggio E in
particolare, possiamo presentare l'oggetto di questo intervento: EUNice.

EUNice è un ambiente integrato per la programmazione object-oriented in E;
in quanto tale, si propone di assistere il programmatore (e non, dunque,
l'analista) nella scrittura di applicazioni object-oriented, con l'obiettivo
di minimizzare i tempi di sviluppo facilitando il riuso di componenti, la
loro documentazione, gestione e integrazione, e rendendo agevole la loro
specializzazione e generalizzazione; EUNice integra inoltre altre attività
di routine, che sono il pane quotidiano dello sviluppo: editing (in futuro,
attraverso editor guidati dalla sintassi), compilazione, debugging,
profiling, esecuzione di copie di sicurezza, ecc.

EUNice si avvale per molti dei suoi compiti di un certo numero di tool
standard, indicati in tabella~1. Molti di questi tool possono essere
configurati dall'utente, attraverso una linea di comando
{AmigaDOS}, ma alcuni di essi dovrebbero in ogni caso rispettare particolari
convenzioni di chiamata (per esempio, EC imposta il numero di linea in cui
si è verificato un errore come proprio codice di ritorno).

\begin{tabstyle}
\begin{tabular}{|l|l|l|}
\hline
Attività       &Strumento        &Default    \\
\hline
Editing        &Editor           &TurboText  \\
Compilazione   &Compilatore E    &EC         \\
Debugging      &Debugger         &EDBG	   \\
Profiling      &Profiler         &AProf	   \\
Gestione versioni,	&vari	&Version, RCS,\\
configurazioni e 	&	&Make, EBuild\\
revisioni&&\\
Documentazione	&Autodoc	         &Autodoc \\
Backup	      &Compattatore/	   &LhA	      \\
               &Archiviatore&\\
Metriche	custom	&tool custom&\\
\hline
\end{tabular}
\par\smallskip\small
Tabella~1: Strumenti integrati in EUNice
\end{tabstyle}

La cooperazione fra questi tool è affidata ad alcune mini-applicazioni di
interfaccia, che hanno lo scopo di fornire una GUI a quegli strumenti che ne
sono privi (per esempio, il compilatore EC o il sistema per la gestione di
versioni e revisioni RCS [7]); le applicazioni di interfaccia, a loro volta,
dialogano direttamente o tramite una libreria con il processo EUNice vero e
proprio, che ha la responsabilità di gestire i file sorgenti in E (per
default, uno per ogni oggetto definito), nonché altri file ausiliari come i
\f{.build} o \f{.makefile} usati dai tool per la gestione delle dipendenze. La
struttura complessiva di EUNice è dunque del tipo client/server, ed è
indicata in figura~\ref{fig:arch}.
\begin{figure}[ht]
\def\epsfsize#1#2{0.1#1}
\begin{center}\tolerance=10000\leavevmode\epsffile[0 0 2480 3300]{eunice/fig1.ps}\end{center}
\caption{\label{fig:arch}\small L'architettura del sistema EUNice}
\end{figure}

È intenzione dell'autore documentare entrambi i livelli di interfacciamento,
tramite la libreria e tramite messaggi, non appena essi saranno giunti ad
uno stato di maturità sufficiente; ciò permetterà l'integrazione di moduli
di terze parti. Per il momento l'interfaccia ricalca quella fornita dagli
oggetti che costituiscono il server.

EUNice è frutto di una ben determinata filosofia di progetto: dare libertà
(e responsabilità) al programmatore piuttosto che limitarne la libertà per
fornire un ambiente più sicuro. Questa filosofia, riassunta in alcune
direttive di progetto, ha determinato le scelte che stanno dietro alle
principali caratteristiche di EUNice. Eccone alcune:

\begin{enumerate}
\item{Il programmatore non deve imparare nuove convenzioni, ma piuttosto
usare i tool che gli sono familiari. Per questo motivo, EUNice si presenta
come un integratore di tool esterni, la maggior parte dei quali
pre-esistenti e familiari ai programmatori. Naturalmente, anche la maggiore
robustezza e flessibilità di tool specifici gioca a favore di questa scelta,
come anche la non-economicità di una reimplementazione custom di funzioni
ormai consolidate.}

\item{Assenza di (ulteriore) strutturazione nei sorgenti. EUNice non impone
una struttura particolare ai file sorgente E, che possono anche essere
redatti esternamente all'ambiente integrato, oppure essere pre-esistenti. Ad
esempio, tipicamente EUNice produce un file \f{.e} per ogni \c{OBJECT}
creato, sotto forma di modulo, ma nessuno impedisce al programmatore di
porre più \c{OBJECT} nello stesso file, insieme a procedure di utilità o
quant'altro. Analogamente, EUNice incoraggia l'uso dei commenti in formato
Autodoc, ma il programmatore è libero di porne quanti ne vuole, dove
ne vuole, senza che l'ambiente forzi una struttura particolare. In assioma:
i \f{.e} sono dominio del programmatore.}

\item{Sicurezza dei progetti. Come ogni tool che manipola file preziosi (nel
nostro caso, i sorgenti E), EUNice pone grande attenzione alla loro
salvaguardia. La sicurezza è dunque implementata in tre livelli: al più
alto, attraverso l'integrazione nell'ambiente di strumenti di backup
periodico dell'intero progetto (comprendendo in ciò, opzionalmente, l'intera
storia delle versioni e revisioni prodotta da RCS); al livello intermedio
tramite la creazione di copie di sicurezza (\f{.bak}) di ogni file \f{.e}
modificato, in numero configurabile (è così possibile, per esempio,
mantenere come copie di sicurezza le ultime tre versioni di ogni file).
Infine, al livello più basso, EUNice fa ogni sforzo per mantenere
l'atomicità di insiemi di cambiamenti al progetto: ogni singola modifica,
infatti, viene bufferizzata e i file \f{.e} originali non vengono modificati
fino a esplicito \c{commit} del programmatore (o, alternativamente, e solo
dopo conferma, al momento della chiusura dell'ambiente).}

\item{Controllo sintattico lasco. Molti degli strumenti di browsing
disponibili per altri ambienti (fra cui molti blasonati tool per Windows),
fanno affidamento sulle informazioni ottenute durante la compilazione per
ricostruire le dipendenze fra moduli e le relazioni di ereditarietà.
Tuttavia, con questo metodo, non è possibile utilizzare tali strumenti se il
codice è incompleto, o presenta errori: limitazione questa che è stata
ritenuta inaccettabile. Di conseguenza, EUNice implementa un parsing ``lasco''
dei sorgenti E, limitandosi a controllare la loro struttura a livello molto
alto (riferimenti a moduli esterni, definizioni di oggetti e metodi),
lasciando al compilatore EC (com'è anche prescritto dalla direttiva 1) il
compito di trovare e segnalare altri errori al momento dell'effettiva
compilazione. Un piacevole effetto collaterale è che il parser custom
implementato è significativamente più veloce di uno tradizionale costruito,
per esempio, con Lex e Yacc.}

\item{GUI intuitiva. Tutto il concetto di ambiente integrato perderebbe di
valore se la sua GUI non fosse intuitiva e, soprattutto, più veloce in
termini operativi della corrispondente interfaccia a linea di comando. Come
esempio eclatante, basterà ricordare la frequenza con cui gli utenti delle
prime (cinque) versioni di Windows ricorrevano alla shell DOS per compiere
moltissime operazioni, piuttosto che affidarsi all'impacciato File
Manager\ldots  Per questo motivo, si è rinunciato a una GUI ultra-sofisticata,
preferendo implementare un minor numero di funzionalità, purché tutte
chiaramente definite e facilmente accessibili (la struttura aperta di
EUNice, d'altra parte, assicura che eventuali funzioni ausiliarie siano
facilmente implementabili tramite moduli aggiuntivi). Un solo esempio per
tutti: l'editing di codice avviene solitamente a livello di singolo
\c{OBJECT} o
\c{PROC} (metodo), anche se è sempre offerta la possibilità di editare un intero
modulo. Ancora, la GUI deve essere configurabile dal programmatore secondo
le proprie abitudini o necessità; un grande aiuto in tal senso viene dalla
scelta di utilizzare il popolare pacchetto MUI di Stefan Stuntz, i cui
meriti sono dimostrati dal sempre crescente numero di applicazioni che ne
fanno uso. Oltre alla configurabilità propria di MUI, ulteriori opzioni
vengono offerte dai vari moduli: per esempio, il Browser di EUNice permette
di mostrare o nascondere singolarmente ciascuno dei ``panes'' che lo
compongono.}

\item{Alta interattività. Per essere produttivo, un ambiente integrato deve
essere veloce. La velocità di cui parliamo, naturalmente, è quella
operativa; non si misura quindi in MHz, ma piuttosto in tempo impiegato (dal
programmatore) per portare a termine determinate operazioni. EUNice cerca di
massimizzare la velocità operativa attraverso molti accorgimenti ``tecnici'';
fra gli altri: uso dei meccanismi di notifica del file system per rilevare
cambiamenti ai file (anche se operati esternamente all'ambiente), controllo
sintattico lasco, re-parsing incrementale delle sole parti del progetto
coinvolte in un cambiamento, bufferizzazione dei file sorgenti. Allo stesso
modo, alcuni accorgimenti ``operativi'' semplificano la vita al programmatore,
come il già citato editing a livello di singolo \c{OBJECT} o metodo. Per
favorire il massimo di interattività, si è scelto di considerare come target
una macchina della classe dell'\A 3000 (una base abbastanza diffusa fra i
programmatori), ma questo non vuol dire assolutamente che macchine di classe
inferiore siano inutilizzabili! Come esempio, in tabella~2 vengono dati
alcuni tempi relativi al parsing e alla compilazione del server EUNice,
nella sua attuale versione, sull'\A meno dotato (500 base); i tempi su
macchine più moderne si riducono in proporzione.}
\end{enumerate}

%\begin{figure}[ht]
%\tablefont\parindent 0pt
%\begin{center}
%{\bf Tab.2:} Tempi di compilazione e parsing del server\\
%EUNice v0.6 su A500 base (68000 @ 7.16\,MHz).
%\begin{tabular}{|l|l|}
%\hline
%Compilazione del          & 10 oggetti, 98 metodi in       \\
%solo server (ec):         & 12 file per complessivi        \\
%                          & 32 Kb di codice E: 38.5 sec.   \\
%\hline
%Parsing dell'intero       & 14 oggetti, 104 metodi in      \\
%progetto (eunice):        & 19 file per complessivi        \\
%                          & 37 Kb di codice E: 12 sec.     \\
%\hline
%Re-parsing (eunice):      & 3 oggetti, 28 metodi in        \\
%                          & 3 file per complessivi         \\
%                          & 13 Kb di codice E: 3 sec.      \\
%\hline
%\end{tabular}
%\end{center}
%\end{figure}

\begin{tabstyle}
\begin{tabular}{|l|l|}
\hline
Compilazione del          & 10 oggetti, 98 metodi in       \\
solo server (EC):         & 12 file per complessivi        \\
                          & 32 Kb di codice E: 38,5 sec.   \\
\hline
Parsing dell'intero       & 14 oggetti, 104 metodi in      \\
progetto (EUNice):        & 19 file per complessivi        \\
                          & 37 Kb di codice E: 12 sec.     \\
\hline
Re-parsing (eunice):      & 3 oggetti, 28 metodi in        \\
                          & 3 file per complessivi         \\
                          & 13 Kb di codice E: 3 sec.      \\
\hline
\end{tabular}
\par\smallskip\small
Tabella~2: Tempi di compilazione e parsing del server
EUNice~v0.6 su \A~500 base (68000 a~7,16\,MHz)
\end{tabstyle}

\paragrafo{I tool integrati}

\sottoparagrafo{Browser}
Il Browser di EUNice permette di esaminare, attraverso una
comoda rappresentazione gerarchica ``ad albero'', il codice corrispondente a
ogni \c{OBJECT} o metodo definito nel progetto; è altresì possibile editare tali
frammenti di codice, ovvero un intero modulo; creare oggetti ex-novo o
specializzare oggetti pre-esistenti, aggiungere, cancellare o ridefinire
metodi per tali oggetti, creare o cancellare moduli contenenti procedure di
utilità o definizioni di dati condivisi. È anche possibile importare ed
esportare moduli e oggetti da/verso progetti differenti, sebbene non sia
ancora previsto alcun controllo di integrazione sulle parti
importate/esportate. In altre parole, il Browser è lo strumento ``principe''
di EUNice, l'ambiente nel quale si svolge la maggior parte del lavoro di
programmazione. In figura~\ref{fig:inter} è mostrato l'aspetto della GUI dell'attuale
prototipo.
\begin{figure}[ht]
\def\epsfsize#1#2{0.3#1}
\begin{center}\tolerance=10000\leavevmode\epsffile[0 0 682 530]{eunice/fig2.ps}\end{center}
\caption{\label{fig:inter}\small L'interfaccia del Browser}
\end{figure}


\sottoparagrafo{Editor}
EUNice permette la scrittura e la modifica dei sorgenti
attraverso un editor esterno, configurabile dall'utente. Per garantire la
sicurezza del file sorgente, l'editor viene invocato soltanto sul frammento
oggetto della modifica (tipicamente, un \c{OBJECT} o una \c{PROC}, ma anche un
commento nel caso degli Autodoc), che EUNice estrae dal sorgente e pone in
un file temporaneo (in \f{T:}, solitamente assegnata a \f{RAM:T/}); il frammento
editato viene integrato nella rappresentazione in memoria del modulo dopo
l'editing, e scritto su disco all'interno del file sorgente appropriato
soltanto dopo il commit da parte del programmatore. Naturalmente, il server
provvede a ``lockare'' il file su disco prima di una modifica in modo da
evitare spiacevoli sovrapposizioni di modifiche. L'editing può anche essere
asincrono, nel qual caso il programmatore potrà avere più finestre di
editing aperte ed effettuare liberamente il cut \& paste da una all'altra (a
condizione, ovviamente, che l'editor prescelto permetta queste operazioni);
EUNice userà i meccanismi di notifica per rilevare la fine dell'editing
(che, a sua volta, causerà il re-parsing dei file interessati).

\sottoparagrafo{Compilatore}
Si tratta, naturalmente, di EC, il compilatore E di
Wouter van Oortmerssen. EUNice sfrutta la capacità di EC di riportare il
numero della linea in cui si è verificato un errore per facilitare
l'immediata correzione dello stesso, come realizzato, per esempio,
dall'utility SCMSG fornita a corredo del compilatore SAS/C. Purtroppo, nella
versione attuale EC interrompe la compilazione dopo la rilevazione del primo
errore, per cui la correzione di un modulo richiede usualmente diversi
cicli. In aggiunta a questa funzionalità, EUNice consente la regolazione dei
parametri di compilazione attraverso una GUI, in maniera globale per tutto
il progetto, con la possibilità di override per singoli moduli. EUNice
identifica inoltre i casi in cui il cambiamento delle opzioni di
compilazione richiede la ricompilazione di un modulo, nonostante il sorgente
relativo non sia stato modificato.

\sottoparagrafo{Debugger}
Anche in questo caso, l'eseguibile utilizzato per default è
EDBG, il debugger di Wouter van Oortmerssen fornito con il pacchetto di
\A E. Poiché EDBG è esso stesso in versione ``beta'', il supporto fornito
si limita a lanciare il debugger quando richiesto dal programmatore.

\sottoparagrafo{Profiler}
Come già per il debugger, il supporto al profiler (che, per
default, è AProf di Michael G. Binz) è minimale, e si limita al lancio dello
stesso.

\sottoparagrafo{Gestione versioni e configurazioni}
EUNice fornisce un'interfaccia
grafica per RCS [7], il sistema di controllo delle revisioni di W. Tichy;
fra le opzioni supportate, oltre naturalmente al check-in e al check-out dei
moduli, vi è la consultazione della storia delle revisioni, l'evidenziazione
delle modifiche apportate a un modulo fra due revisioni e molte altre. La
gestione delle configurazioni è (anche) affidata al classico Make; la
generazione dei file \f{.makefile} o \f{.build} di base è, peraltro, a carico
dello stesso EUNice, come anche la generazione delle stringhe di versione
(\c{\$VER: ...}) da inserire nei sorgenti e nell'eseguibile.

\sottoparagrafo{Documentazione}
Quando i sorgenti E contengono commenti nel formato
Autodoc [8], EUNice provvede a estrarli e a produrre un file di
documentazione nei formati ASCII e (opzionalmente) AmigaGuide, usando i
tool standard Autodoc e AD2HT, entrambi da {\az Commodore-Amiga}.

\sottoparagrafo{Metriche}
Oltre ai servizi tradizionali dell'ambiente di
programmazione, EUNice intende offrire alcuni strumenti per il controllo
della qualità del codice. In tale contesto, vengono fornite alcune metriche
(calcolate off-line) sulla struttura object-oriented dell'applicazione
(numero di oggetti, profondità dell'albero, numero di metodi per oggetto,
ecc.) e sullo stile di codifica (lunghezza delle procedure, diffusione dei
commenti, numero di parametri, ecc.). Un rapporto più dettagliato viene
fornito a proposito di quegli oggetti o procedure che presentano rispetto
alla media una deviazione superiore a una soglia prefissata. Il
programmatore è quindi libero di usare i dati così ottenuti per uniformare
il suo codice a determinati criteri (come pure è libero di ignorare il
tutto).



\paragrafo{Stato del progetto}
\noindent Al momento della redazione di questo articolo, EUNice è ancora in corso di
completamento. Tutte le funzionalità di base (parsing incrementale del
codice E, editing di frammenti, bufferizzazione delle modifiche, generazione
della gerarchia ``is-a'' per l'ereditarietà degli oggetti e di quella ``uses''
per l'inclusione di moduli esterni) sono già testate e funzionanti. Rimane
ancora da definire l'interfaccia del server nonché, di conseguenza, tutta
quella della libreria; devono altresì essere completati i moduli client,
alcuni dei quali sono allo stadio di prototipo. È invece completa e
funzionante, sebbene non del tutto testata, la prima versione del
Browser, da cui ha tratto origine l'intero progetto EUNice. Questo tool, di
nome EBOMB (E-Based Object and Method Browser), sebbene non consenta
l'editing del codice, si dimostra comunque prezioso per studiare
applicazioni scritte in E object-oriented senza affondare fra i sorgenti.
Esso condivide buona parte della filosofia di progetto con EUNice, ed è
stato infatti utilizzato per lo sviluppo di quest'ultimo. A differenza del
fratello maggiore, EBOMB è scritto in stile procedurale, e non
object-oriented; nonostante ciò, i tempi di parsing delle due versioni sono
sostanzialmente identici, a riprova del fatto che la scrittura
object-oriented (almeno\ldots  in E!) non impone alcuna penalità in termini di
prestazioni rispetto a una tradizionale. Anche EBOMB, come i client di
EUNice, fa uso di MUI per la sua interfaccia grafica (figura~\ref{fig:EBOMB}).
\begin{figure}[ht]
\def\epsfsize#1#2{0.3#1}
\begin{center}\tolerance=10000\leavevmode\epsffile[0 0 682 530]{eunice/fig3.ps}\end{center}
\caption{\label{fig:EBOMB}\small EBOMB, il predecessore di EUNice}
\end{figure}



\paragrafo{Sviluppi futuri}
\noindent Come già si è detto, è intenzione dell'autore documentare l'interfaccia del
server EUNice e quella della libreria associata per permettere a moduli di
terze parti l'integrazione nell'ambiente di sviluppo. Un'interfaccia ben
definita si rivelerà preziosa per consentire il completamento graduale di
EUNice, nella forma che è stata illustrata in precedenza. Fra i successivi
sviluppi, si può prevedere un tool per le metriche più esaustivo, che tracci
anche le informazioni ricavate dagli archivi di RCS; altro passo importante
potrebbe essere la gestione della multi-utenza e della concorrenza per lo
sviluppo distribuito di applicazioni.

Altro ramo di grande interesse è quello relativo agli strumenti di ausilio
per il riuso, che consentano l'archiviazione e il reperimento di oggetti
attraverso l'individuazione di categorie funzionali, estendendo le attuali
funzioni di import/export; molte tecniche in questo campo sono illustrate in
[10], mentre una panoramica in lingua italiana sullo stato dell'arte è
contenuta in [11]. Allo stesso modo, l'architettura aperta di EUNice
permette di immaginare strumenti di ausilio al reverse engineering,
soprattutto per quanto riguarda l'estrazione di viste a differenti livelli
di astrazione partendo dal codice [12].

L'opportunità di queste possibili estensioni, visto l'impegno richiesto,
dovrà comunque essere valutata a fronte della situazione globale del mercato
\A nel prossimo futuro.



\paragrafo{Ringraziamenti}
\noindent L'autore desidera ringraziare in primo luogo l'autore di \A E, Wouter van
Oortmerssen, per aver messo a disposizione della comunità \A un
eccellente, flessibile, veloce, pratico linguaggio per la programmazione
object-oriented, fornendo inoltre una serie di tool di tutto rispetto per
affiancarlo. Ringraziamenti altrettanto sentiti vanno a Stefan Stuntz e ad
Eric Totel, autori, rispettivamente, di MUI e di MUIBuilder, i cui meriti
sono abbastanza noti da non richiedere un'ulteriore illustrazione in questa
sede.

Per evenutali (gradite) richieste di chiarimenti e suggerimenti, contattate
direttamente l'autore.

\begin{thebibliography}{10}
\bibitem{KARL} E.-A. Karlsson, J.-M. Morel.  The Impact of Reuse on Software
Quality. Lecture Notes in Computer Science 926: \emph{Objective Software
Quality}, Paolo Nesi (ed.), Springer-Verlag, 1995.

\bibitem{PESCIO} C. Pescio. Object Oriented Technology. Serie di articoli su
\emph{Computer Programming}, Infomedia, a partire dal numero 34 (marzo 1995).

\bibitem{MEYERS}B. Meyers. \emph{La produzione del software
object-oriented}. Gruppo
Editoriale Jackson, 1991.

\bibitem{WOUTER}W. van Oortmerssen. \emph{\A E v3.1a: Compiler for the E
Language}.
Documento AmigaGuide distribuito con il pacchetto (shareware) del
compilatore E.

\bibitem{HUL}J.R. Hulance. \emph{A Beginner's Guide to \A E}. documento AmigaGuide
distribuito con il pacchetto (shareware) del compilatore E.

\bibitem{GERV}V. Gervasi. \A E. Serie di articoli su \emph{Amiga Magazine}, Gruppo
Editoriale Jackson.

\bibitem{TICHY}W. Tichy. \emph{RCS: A System for Version Control}. \emph{Software: Practice
and Experience}, pagg.~575--585, luglio 1985.

\bibitem{AUTODOC}{\az Commodore-Amiga}. \emph{Autodoc Style Guide}.
Distribuito con il pacchetto
Autodoc di Bill Koester, giugno 1990.

\bibitem{GHEZZI}C. Ghezzi, A. Fuggetta, S. Morasca, A. Morzenti, M. Pezzè. \emph{Ingegneria
del Software}. Mondadori Informatica, 1991.

\bibitem{KRUEGER}C.W. Krueger.  Software Reuse. \emph{ACM Computing
Surveys}, Vol.~24, No.~2, 1992.

\bibitem{MONTA} C. Montangero (ed.). \emph{Metodi e strumenti per il progetto del
software}.
Franco Angeli, 1995.

\bibitem{CARLINI} U. De Carlini, A. Cimitile. \emph{Metodologie, tecniche e strumenti di
reverse engineering}. Franco Angeli, 1995.
\end{thebibliography}




\autore{%
Vincenzo Gervasi\\
Via A. Bennicelli 44\\
I-00151 Roma}
{Fidonet: Vincenzo Gervasi 2:335/376.18}

\citazione{\selectlanguage{english}%
\emph{The lesser-known programming languages \#10: SIMPLE}\\
{SIMPLE} is an acronym for Sheer Idiot's Monopurpose Programming Language
Environment.  This language, developed at the Hanover College for
Technological Misfits, was designed to make it impossible to write code
with errors in it.  The statements are, therefore, confined to BEGIN,
END and STOP.  No matter how you arrange the statements, you can't make
a syntax error.  Programs written in {SIMPLE} do nothing useful.  Thus
they achieve the results of programs written in other languages without
the tedious, frustrating process of testing and debugging.}{}
