Newsgroup: it.comp.lang.visual-basic
Titolo: [!] Cosa pensa Balena di Gosub e Goto

Seguendo il cosiglio dell'insostituibile Hal, mi sono comprato anche io PC
Professionale con in allegato il libro di Balena sul VB (ce l'avevo già, ma
un'altra copia da portare in treno fa sempre comodo).
Rileggendolo ho trovato a pagina 165 un commento riguardo Gosub e Goto, che
mi ha fatto tornare in mente una discussione di qualche anno fa fatta sul NG
approposito della convenienza o meno dell'uso del Gosub.
Praticamente Balena dice che il Gosub è a volte preferibile rispetto ad una
chiamata di Sub o Function (ma anche lui sottolinea come stranamente sia in
compilato fino a 7 volte più lento di una chiamata ad una routine esterna).
Meno male, se lo dice lui, mi sento un po' meno dinosauro ad usarlo ogni
tanto.
Mi ha invece stupito che dica che anche il Goto a volte può essere usato,
per evitare troppe Exit For o Exit Do.
E' vero che quando uno è molto bravo può permettersi di andare contro alle
regole, ma nel suo caso genio e sregolatezza imperano. ;-)
Commenti?
Ciao
*Roby*

Commenti?
Mi fa venire in mente un articolo che avevo letto del Mandelbrot Set che
difendeva a spada tratta i Variant :-(
A dire il vero uso il GoTo in solo tre casi:
1. On Error Goto <etichetta>
	qui non c'e' niente da fare, il try...catch...finally e' stato
	implementato solo a partire da 
vb.net
;
2. Quando, in un ciclo For...Next o Do...Loop mi servirebbe un
	continue, che in vb manca del del tutto;
3. Non uso quasi mai Exit Sub / Exit Function, ma, piuttosto,
	Goto <etichetta_di_uscita>: li' scrivo il codice di pulizia
	di tutto quello che potrebbe essere ancora allocato
	per i piu' svariati motivi. In questo modo ho un solo
	punto di entrata nella ed un solo punto di uscita dalla
	procedura: e' quasi impossibile che mi rimanga un recordset 
	aperto quando non serve piu' o la clessidra impostata
	quando dovrebbe esserci il cursore normale.
-- 
ciao, hal

> "Roberto Piazzolla" [...]:

Non vorrei sbagliare ma il primo libro di Balena che ho letto era sul BASIC
dello Spectrum... E leggi cosa ne dice lui stesso:
http://www.apress.com/vbat10/FrancescoBalena/
A me e' capitato che, da un giorno all'altro... puff... non ho piu' trovato
GOTO e GOSUB nei miei programmi e mi sono un po' sorpreso. Poi ci ho
riflettuto ed ho notato che e' successo, piu' o meno, in concomitanza con
l'avvenuta digestione delle classi.
--
Ciao.
Maurizio
--------
?SPQR(C)
 X
--------

 di tutto quello che potrebbe essere ancora allocato
Questa cosa mi da' da pensare. Io normalmente non uso il goto neppure per
questo, ma sinceramente sarebbe comodo.
Sono un po' combattuto, ma mi sa che finisce che lo riabilito anche io. :-)
Ciao
*Roby*

 l'avvenuta digestione delle classi.
Beh, non credo si possa dire che Balena non abbia mai digerito le classi,
eppure lui del gosub ne parla bene.
Ciao
*<Roby*
P.S.
Benritrovato. Aspettavo l'occasione giusta per dirtelo senza andare OT. :-)

 
Ah ha! allora non sono l'unico ad usarlo in questo modo. Mi sentivo 
cosi' in colpa ogni volta che qualcuno veniva sgridato ... :-)
In questo caso non so se esista un modo migliore; se esiste postatelo, 
please!
ciao
		maxx

[CUT]
E' vero un Goto e Gosub creano un po' di confusione,
ma io odio i puristi della programmazione, se un goto
mi fa risparmiare 2 righe di codice e 10 minuti di tempo
perchè non usarlo.
Quando ce vo' ce vo'...
                                                danilo

 Quando ce vo' ce vo'...
Appunto

 Ohh! Finalmente qualcuno che mi capisce. ;-)
Anche a fondamenti di infromatica tanti anni fa se ne era parlato e la
conclusione era di evitarlo il più possibile ma non demonizzarlo: ci sono
casi in cui il codice risulta più leggibile con un goto che con i pasticci
che spesso si fanno per evitarlo...
Ciao

 E cos'e' sto try catch finally?
Il sistema che M$ ha escogitato per costringerti a studiare 
VB.NET
 sui
manuali.
Se provi ad usare la stessa gestione errori del VB non funziona, quindi alla
fine provi a prendere il manuale (try catch finally [the manual]) ;-)
No, in realtà è l'alternativa 
VB.NET
 alla On error che (a quanto ho capito)
funziona così:
Try ' qui inizia la gestione errori locale
  ' qui vanno le tue righe di programma
Catch ' qui si salta in caso di errore
  ' qui va la gestione dell'errore
Finally ' qui si arriva se non ci sono errori, oppure dopo che sono stati
gestiti.
  ' qui continua il programma
In questo modo la gestione errori è contenuta completamente in poche righe.
Per ottenere lo stesso effetto con VB dovevi usare 2 Goto (una per la On
error, e una per saltare le righe della gestione errori).
Ciao
*Roby*

cos'è il gosub?
e il goto?
perché mi dici queste parole arcane?
^_^
-> GbC
http://www.gbcweb.com

 ha scritto nel messaggio
news:3CD22B06...@laserinforma.com...
| > qui non c'e' niente da fare, il try...catch...finally e' stato
| > implementato solo a partire da 
vb.net
;
|
| E cos'e' sto try catch finally?
non vorrei dire boiate ma arriva dal C.
--
[ Penguin At Work ]
-> 
http://web.tiscali.it/penguinatwork/
-> aka Fustino Di Dixan while working

 perché mi dici queste parole arcane?
Parole arcane? Messere, mi permetta lo spiego:
GoSub: lo salto in avanti di tal guisa che lo cervello di sabbia cambi
pensare, ma acconsenta al ritorno.
Goto: lo salto in ogniddove, all'interno della competenza sua, acciocchè lo
cervello di sabbia abbia a che cambiare pensieri.
Attento viandante, perchè da lì non v'è ritorno.
Tanto dovevo, e tanto ho dato
Ossequiando
*Roby*.

 ha scritto nel messaggio
news:aatosc$dl5f5$1...@ID-94194.news.dfncis.de...
| Parole arcane? Messere, mi permetta lo spiego:
|
| GoSub: lo salto in avanti di tal guisa che lo cervello di sabbia cambi
| pensare, ma acconsenta al ritorno.
|
| Goto: lo salto in ogniddove, all'interno della competenza sua, acciocchè
lo
| cervello di sabbia abbia a che cambiare pensieri.
| Attento viandante, perchè da lì non v'è ritorno.
ROTFL :) che fumate qua?
non che ci tenga a fumare... pero' dovreste parlare
cosi' piu' spesso.


 Parole arcane? Messere, mi permetta lo spiego:
[gut]
:DDDD
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 cosi' piu' spesso.
piu' che fumarla, mi sa che e' proprio caduto nella pignatta.
robelix...
il 'cervello di sabbia' risulta da un sondaggio sulla materia grigia
prevalente ?

 perché mi dici queste parole arcane?
[romanesco]
    Ar cane ? E chi ha parlato de 'n cane ?
    A Ggiava, che stanno addì attè, pe' caso ?
[/romanesco]
Bye, G.

 cosi' piu' spesso.
Già accusano i guru di essere incomprensibili... figurati se si mettono a
parlare così sempre! :P

"Paperino" <non...@lo.dico> ha scritto

che hai detto ? nun stavo a senti' ...
e che vorra' mai di' gibbicci' co' robbelix ar cane ?
ie serve un interpetre ?
o ie basta un compilatore ?
j.dll
--
tentiamo un imbonimento per domenica prossima, vero hal ?
j.se.non.fossi.una.cagnetta.per.bene.mi.toccherei.le.palle


ar cane?
-> GbC
http://www.gbcweb.com

 j.se.non.fossi.una.cagnetta.per.bene.mi.toccherei.le.palle
I novanta minuti piu' lunghi degli ultimi anni :-(
-- 
ciao, hal.varorecoba


 sulla materia grigia prevalente ?
Beh, è l'unico modo con cui un uomo dell'anno mille poteva descrivere un
oggetto quasi-pensante fatto di silicio. ;-)
In media stat virus (come dicono alla MacAfee)
*Roby*
P.S.
Ecco, siamo di nuovo completamente OT. :-(

 ha scritto nel messaggio
news:aatdog$dff87$1...@ID-94194.news.dfncis.de...

Si funziona così, ed è copiata pari pari da Java
Try
     prova il codice
Catch
    gestione eccezione
Finally
    ci siamo

 parlare così sempre! :P
A qul punto potreste anche scrivere le vostre divinazioni su foglie, stile
Sibilla Cumana...
Male che vada, noi "pivellini" potremmo fumare suddette foglie, inizieremmo
cosi' a vaticinare anche noi, ed entreremmo in un clamoroso loop (giusto per
restare in tema di GOTO...)! :)
Ciao,
- SonicBoom -

 non vorrei dire boiate ma arriva dal C.
Non dal C, non dal C... il C non ha la gestione delle eccezioni,
anzi... non ha proprio nessun meccanismo di gestione degli errori.
Ciao.
--
BSD is for UNIX-lovers -- linux is for Windows-haters.

 le righe della gestione errori).
Non è così semplice. In realtà quello che puoi ottenere (riguardo la
gestione degli errori) ora in 
VB.NET
 con VBb non era proprio
possibile.


 Si funziona cosě, ed č copiata pari pari da Java
Sono molti i linguaggi che hanno try... catch, non č certo
un'invenzione di Java.


"H.P.L." <u...@vaila.ble> ha scritto nel messaggio
news:FCwA8.560$zW3....@news1.tin.it...
| Fustino di Dixan wrote:
| >> E cos'e' sto try catch finally?
| > non vorrei dire boiate ma arriva dal C.
| Non dal C, non dal C... il C non ha la gestione delle eccezioni,
| anzi... non ha proprio nessun meccanismo di gestione degli errori.
:p ... il c++?? sara' che ricordo male
ma il try e il catch li ho visti.
avro' bevuto? ... maybe, maybe.
saluti


 sregolatezza imperano. ;-)
Se ce ne fosse un reale bisogno non vedo proprio perché non
utilizzarlo. Però devo dire che non mi è mai capitata una sola volta
in cui mi è stato necessario utilizzarlo (escludendo l'On Error...).


 saluti
Il C++ ha il costrutto try...catch... (senza il finally), il C no.
In C puoi trovare __try...__catch..., ma è un'estensione
proprietaria di VC++, e pertanto non fa parte del linguaggio (non
funziona con altri compilatori).
Ciao


 possibile.
Si, ho semplificato un po' troppo.
In 
VB.NET
 hai a disposizione anche la nidificazione dei blocchi di Try -
Catch, e il trace di tutte le istruzioni e chiamate che hanno portato
all'errore. In compenso non puoi lavorare in debug mode con la stessa
facilità con cui lo facevi con VB.
Gioie e dolori, come al solito.
Ciao
*Roby*


infatti hai detto una boiata ;))
semmai arriva da C++ oppure, se preferisci, da Java o da Delphi (tanto per
citare solo i linguaggi object oriented che conosco);
ciao


se non ci fossero Goto e Gosub non saprei scrivere neanche un programma per
fare 2+2... :-)
sono cresciuto col QBasic, a pane, Goto e marmellata... :-)
Mario

 I novanta minuti piu' lunghi degli ultimi anni :-(
90 minuti per toccarsi le palle?? Ma che orchite c'hai?
Ciao
*Roby*
P.S.
Ripensandoci nel calcio la scaramanzia č parecchio importante. Di solito
alla fine vince la squadra che ha toccato le palle piů spesso...
P.S.2
Per espiare l'OT calcistico, mi autoinfliggo una punizione all'angolo.

Per espiare l'OT calcistico, mi autoinfliggo una punizione all'angolo.
Ma no, quando sono divertenti, gli OT sono la cosa piu' interessante da
leggere :-)
-- 
ciao, hal

 Per espiare l'OT calcistico, mi autoinfliggo una punizione all'angolo.
vabbe', perdonato, ormai si parla solo di vbtennis, vbnet...

vabbe', perdonato, ormai si parla solo di vbtennis, vbnet...
venerdi' sera tardi: e' l' ora dell' OT :-)
potremmo istituzionalizzarla ?
uhm, no:
Legge di Dunn
Una pianificazione attenta non potrà mai sostituire una bella botta di culo. 
-- 
ciao, hal.ToNight();

 stessa facilità con cui lo facevi con VB.
Questo non dipende però dal linguaggio ma dal fatto che non è
più interpretato.


 Una pianificazione attenta non potrà mai sostituire una bella botta di
culo.
Bellissima!! :-)
Ciao
*Roby*

 più interpretato.
Dipenda da quello che vuoi, è un dato di fatto.
Anche VB non è un interpretato quando stai fuori dall'IDE. Si vede che con
.NET non avevano voglia di scriversi *anche* un interprete.
Ciao
*Roby*

 in cui mi è stato necessario utilizzarlo
Se la mettiamo sul piano della "necessità", il Goto e il Gosub si potrebbero
eliminare, ma qui stiamo parlando di comodità.
Hal ha evidenziato come ad esempio con gli Exit Sub si rischia sempre di
lasciare aperto qualcosa, mentre se si usasse un GoTo Exit, dove ad Exit ci
sono tutte le funzioni di chiusura, questo problema non si porrebbe.
Certo, tu puoi obiettare che allora puoi evitare la Sub, e gestire invece
una classe che nel costruttore inizializzi tutto e nel distruttore lo
deinizializzi, ma è effetivamente più comodo che usare il Goto?
Stesso discorso per il GoSub. se ti riutilizzare solo un paio di volte la
stessa porzione di codice all'interno di una unica routine, che però usa
molte delle variabili inizializzate in quella routine e le manipola, è più
comodo e pulito un semplice Gosub, oppure creare una Sub che accetti tutti i
parametri ByRef e li modifichi in esterno?
Io incomincio ad avere dei dubbi. Se poi lo dice pure Balena...
Ciao
*Roby*

 *anche* un interprete.
Con il cambiamento che c'è stato nel linguaggio, lo sviluppo
di un interprete sarebbe stato un po' troppo oneroso.


 Stesso discorso per il GoSub.
[cut]
Regole fondamentali del programmatore:
una funzione = un compito
una funzione max = max 20 - 30 righe


Una pianificazione attenta non potrà mai sostituire una bella botta di culo. 
LOL Questa mi mancava! ;)
-- 
Visita il sito comune del NG: 
http://www.it-lang-vb.net
Visit: 
http://www.hardwaretips.com

 di un interprete sarebbe stato un po' troppo oneroso.
Certo, ma poi è anche comodo tenersi da parte delle cose utili che possono
servire per essere sicuri di vendere, entro un paio d'anni, l'inevitabile
versione 2 dell'ambiente di sviluppo .NET. ;-)
Ciao
*Roby*

 una funzione max = max 20 - 30 righe
Anche qui siamo d'accordo, ma il Gosub è equiparabile ad una funzione con
passaggio implicito di parametri. Non la devi contare all'interno del
computo delle righe della routine, perchè la routine termina prima che inizi
il codice del GoSub.
Si tratta solo di un problema visivo: invece di leggere End Sub seguito da
una dichiarazione di una nuova funzione (da usare al posto della gosub),
leggerai Exit Sub seguito da un commento che dice ' Inizio del codice di
gosub, e dalla label che dovrà ovviamente avere un nome quanto più possibile
autoesplicativo.
Però in questo modo hai il vantaggio di avere il passaggio di parametri
implicito, diminuisci il numero di funzioni utilizzate, ed hai un codice
quanto più possibile autocontenuto.
Anche avere tantissime funzioni è un problema: ti è mai capitato di cercare
una funzione di cui non ti ricordi esattamente il nome passandoti tutte le
funzioni presenti, e scoprire che sono maledettamente troppe? ;-)
Ciao
*Roby*

 dell'ambiente di sviluppo .NET. ;-)
No, questa è una "funzionalità" che se ne è ormai andata...
E non hanno bisogno di questo per vendere la versione
successiva di 
VS.NET
, gli basta fare in maniera che non si
adatti alle modifiche che ci saranno nei linguaggi (come la
già annunciata comparsa dei template nella prossima versione
di C#).


 troppe? ;-)
No, l'utilizzo che io faccio del VB non mi crea questi
problemi :-P


Design errato ;-)
Dubito ergo sum ;-)
Ti faccio un esempio:
<codice>
Private Function QueryConMilleJoinCheCiMetteUnaVita(<parametri>) As Long
    On Error Goto eh          ' sono troppo pigro per scrivere ErrorHandler per esteso :-P
    Dim mi_rs As ADODB.Recordset
    Dim mi_rsOther As ADODB.Recordset
    Dim mi_IsTrans As Boolean              ' flag che mi ricorda se ho attivato una transazione
    Screen.MousePointer = vbHourglass
     [.... codice di apertura del primo recordset ...]
     If (mi_rs.EOF) Then
          MsgBox "Lazzarone, l'archivio e' vuoto :-PPP", vbCritical
          Goto ef
     End If
     If (False = mi_rs!PossoFareQuestaOperazione) Then
           MsgBox "Siccome non sei ancora maggiorenne devi aspettare :-(", vbCrititcal
     End If
     If (Date > mi_rs!DataScadenza) Then
           MsgBox "La fattura del programmatore e' scaduta :-(", vbCritical
     End If
     [... apre il secondo recordset in base ai valori contenuti in alcuni campi
          del primo recordset, chiude il primo recordset ed avvia una transazione ...]
     Do Until mi_rsOther.EOF
          If (False = mi_rsOther!CampoFlag) Then GoTo continua
 
          [..... operazioni varie ....]
continua:
          mi_rs_Other.MoveNext
     Loop
ef:    ' anche qui, troppo pigro per scrivere exit_function
    On Local Error Resume Next
    If (mi_IsTrans) Then g_Connection.Rollback
    If (Not mi_rs Is Nothing) Then mi_rs.Close: Set mi_rs = Nothing
    If (Not mi_rsOther Is Nothing) Then mi_rsOther.Close: Set mi_rsOther = Nothing
    ' questa potrebbe essere sostituita da un semplice oggetto che,
    ' uscendo dallo scope, nel Class_Terminate ripristina il puntatore del mouse
    ' ma col c@%%0 che vado a sostituire chissa' quante righe di codice
    ' in programmi che eredito :-P
    Screen.MousePointer = vbDefault
    Exit Function
eh:
    ' ShowError e' una ipotetica funzione di visualizzazione maschera di errore
    ' che permette all' utente di scegliere cosa fare:
    ' continuare, terminare, stampare la schermata, mandarmi una mail, pagarmi la fattura, ecc.
    ' l' esito e' dedotto da un enumeratore che rende leggibile il valore di ritorno
    Select Case ShowError (TypeName(Me), "QueryConMilleJoinCheCiMetteUnaVita")
    Case eShowError.Ritenta: Resume
    Case eShowError.Successiva: Resume Next
    Case eShowError.Esci: Resume ef
    Case eShowError.Termina: QuitApp
    Case Else: Resume ef
    End Select
 
End Function
</codice>
Come si potrebbe migliorare questo design, tenendo conto che, spesso ci si
inserisce in codice gia' esistente e non sempre ben documentato?
-- 
ciao, hal

 sempre ben documentato?
Lo hai scritto sopra tu stesso. La soluzione è riorganizzare
il codice in maniera diversa. D'altra parte, come ho già
detto, questa funzione:
1) svolge troppi compiti
2) è troppo lunga.
Il fatto che non valga la pena di ristrutturare il codice non
significa che questo è il giusto design, ma che il design è
stato sbagliato fin dall'inizio, e che tu sei dovuto scendere
ad un compromesso.
Ma questo è e rimarrà sempre codice mal scritto (del quale tu
non hai alcuna colpa, ovviamente).
