Modulo Info [Gambas]


Continua il mio (piccolo) lavoro per portare in Gambas moduli e classi che contengano funzioni delle quali il gambero blu è sprovvisto.

Ultimamente mi sono accorto che tra gli utenti di questo linguaggio c’è interesse verso le caratteristiche dell’hardware su cui un programma gira. Armatomi di pazienza e di tanta, tantissima, cioccolata calda, ho passato il tempo libero degli ultimi giorni a trovare e strutturare un algoritmo per ovviare a tali problemi. La soluzione è stata un pò di sano codice e l’uso di lshw.

Per chi non lo sapesse lshw è un software da linea di comando che permette di conoscere per filo e per segno tutto l’hardware presente sul proprio sistema.

Partendo da questo presupposto ho creato una serie di filtri (secondo me molto funzionali) hai quali ho affidato la gestione delle funzioni dei diversi device. Attualmente sono ancora al lavoro, e quindi il codice è instabile e in fase beta, ma cercavo qualcuno volenteroso che testasse il modulo sul proprio computer magari confrontando i risultati con un lshw lanciato da terminale. In questo modo potrei avere feedback da diversi utenti e da diversi sistemi.

Per ora il codice mostra info su: core, memoria RAM, cache, PCI, USB

Per maggiori informazioni visitate il link nella colonna di destra.


Nella stessa pagina, oltre ovviamente ai sorgenti da scaricare, trovate anche i link alla lista dei prototipi delle funzioni attualmente implementate ed il link al changelog delle modifiche.

Didattica Gambas: Gestione errori (parte 2)


Come promesso nel precedente post ora vedremo alcuni esempi dell’uso delle funzioni che Gambas offre per la gestione degli errori.

Immaginiamo ad esempio di voler eliminare un file il cui percorso è contenuto nella variabile di tipo stringa di nome $indirizzo. La prima cosa da fare e indicare, mediante il comando KILL il file da eliminare:

KILL $indirizzo


Così come è scritta l’istruzione, non si potrà mai sapere se essa sarà eseguita con esito positivo o se solleverà un’eccezione. Si usa pertanto la seguente sintassi:

TRY KILL $indirizzo


In questo modo diciamo a gambas di
tentare l’esecuzione di KILL e di restituirci l’eventuale errore se esso dovesse presentarsi. Come si fa allora ad analizzare l’esito? Come detto in precedenza si ricorre al valore che in questo momento assumerà ERROR. Essa potrà valere o TRUE, sapremo così che c’è stato un errore, o FALSE, esplicando la riuscita dell’istruzione.

Si usa pertanto la seguente sintassi:

IF ERROR THEN PRINT "Errore nell'istruzione kill"


Si vede facilmente che IF analizza lo stato di ERROR e se esso è TRUE allora stamperà nel terminale la stringa racchiusa tra gli apici.

Immaginiamo ora di voler sapere quale errore in particolare si sia presentato. Per il nostro scopo basterà utilizzare le funzioni interne alla classe Error.

Analizziamo la seguente sintassi

TRY KILL $indirizzo
IF ERROR THEN PRINT Error.Text


Con queste due righe di codice abbiamo detto a gambas di provare a rimuovere il file $
indirizzo e di scrivere nel terminale il testo dell’errore, se presente, così come esso viene restituito dal sistema. Infatti Error.Text conterrà il testo dell’errore qualora esso esista.
In modo analogo possiamo analizzare il codice colpevole dell’errore e il punto del sorgente in cui esso si è presentato. Basterà infatti analizzare rispettivamente le funzioni Error.Code ed Error.Where. Un esempio di codice potrebbe essere:

TRY KILL $indirizzo
IF ERROR THEN
PRINT "Testo errore: " & Error.Text
PRINT "Codice errore: " & Error.Code
PRINT "Errore presente in: " & Error.Where
END IF

L’uso combinato di TRY ed ERROR è molto semplice e permette al programmatore di ovviare con facilità ad eventuali problemi che potrebbero causare il crash del programma.

Vediamo ora l’uso di FINALLY e CATCH

Come si è detto FINALLY, posto prima di un blocco di codice, permette di eseguirlo ignorando gli errori che invece di essere analizzati vengono semplicemente propagati fino alla fine del blocco. L’uni modo che si ha per analizzare gli errori è l’uso di CATCH. Vediamo un codice d’esempio prelevato dalla documentazione di gambas e leggermente modificato:

SUB PrintFile($indirizzo AS STRING)

DIM hFile AS File
DIM $Stringa AS STRING

OPEN FileName FOR READ AS #hFile

WHILE NOT EOF(hFile)
LINE INPUT #hFile, $Stringa
PRINT $Stringa
WEND

FINALLY ' Lo esegue sempre
CLOSE #hFile

CATCH ' Esegue solo se c'è un errore
PRINT "Non è possibile stampare il file "; $indirizzo

END


Il codice è facilmente comprensibile. Esso si limita all’apertura di un file di testo da stampare riga per riga nel terminale. Solo alla fine si usa FINALLY per provare a chiudere il file. Se tale operazione non è consentita (e solo in quel caso) esegue l’istruzione che succede CATCH.

Anche l’uso di queste ultime due istruzioni è tanto semplice quanto potente e permette di scrivere sempre codice di ottima qualità con strumenti di facile utilizzo.

Didattica Gambas: Gestione degli errori


Quando si programma in Gambas molto spesso si fa l’errore di dare per scontato che una determinata azione andrà sempre a buon fine e che pertanto sarà eseguita in tutti i casi.

Essendo Gambas un linguaggio diverso dai suoi simili di più basso livello, tipo C, non si ha molto la cognizione della gestione degli errori e delle eventuali anomalie che possono presentarsi da situazione a situazione e da macchina a macchina.

Non prevedere gli errori significa dare in mano all’utente finale un programma instabile che potrebbe crashare miseramente per una nostra leggerezza nel codice.

Vediamo un pò gli strumenti che il gambero offre per cercare, intercettare e gestire gli errori.

TRY

Try, che letteralmente vuol dire “prova”, è un’istruzione utile a intercettare eventuali errori che potrebbero presentarsi sul codice che proviamo ad eseguire.

Immaginiamo ad esempio di voler aprire un file. Aprire un file è un operazione che può fallire per diversi motivi, mancanza di spazio in memoria, file inesistente o errori di sintassi del codice. Sarebbe per buona norma pertanto usare try prima del codice di gestione.

Come facciamo allora a scoprire per quale motivo il nostro codice non ha funzionato?
Per tale scopo ci viene in aiuto il successivo strumento: Error.

ERROR

Error non è un’istruzione ma è una variabile di tipo booleano (ovvero che può assumere solo il valore TRUE, cioè 1 logico, o FALSE, cioè 0 logico). Essa avrà valore 1 se nel codice analizzato da try si è presentato un errore mentre varrà 0 se il codice ha svolto il suo lavoro.

Error non è solo una variabile ma con lo stesso nome si indica anche una classe, sempre correlata all’esecuzione di try, che gestisce l’errore in ogni suo aspetto.
Tra le sue proprietà vediamo in particolare:

1) Code:
Richiamabile da Error.Code, restituisce il codice del sorgente Gambas che ha generato l’errore;

2) Text:
Richiamabile da Error.Text, restituisce il testo dell’errore così come si presenta al sistema;

3) Where:
Richiamabile con Error.Where, indica la parte del codice (Form, classe, modulo, rigo) in cui è avvenuto l’errore.

FINALLY

Finally è una particolare istruzione che posta prima di un blocco di codice forza l’interprete ad eseguirlo anche se si presentano errori. Qualora dovesse presentarsi un errore, esso sarà ignorato e si propagherà fino alla fine del blocco mentre il codice sarà eseguito, dove possibile, o ignorato. Per intercettare alla fine gli errori presentatisi si ricorre ad un’altra istruzione: Catch

CATCH

Catch è posto prima di un blocco di codice adibito alla gestione degli errori solitamente propagatisi per via della presenza di Finally.

Nel prossimo post vedremo alcuni esempi dell’uso di quste istruzioni che dovrebbero diventare uno strumento da utilizzare in maniera adeguata nei propri codici.