Autore Topic: [Risolto]Diamo un taglio alle variabili globali  (Letto 3639 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
[Risolto]Diamo un taglio alle variabili globali
« il: 21 Settembre 2010, 16:22:27 »
La sapete l'ultima del Ministero degli Interni di Gambas?
Per rientrare nel budget di spesa indicato nella fianaz-Memory bisogna apportare un taglio deciso all'impiego di variabili globali nei programmi comunitari.  :rotfl: :rotfl:
Perciò sto cercando di uniformarmi alle disposizioni e, attraverso i vari metodi su cui sto impegnando la mia mente in questo momento, operando un taglio di qua ed un taglio di là, sto diminuendo drasticamente la presenza di variabili globali nel mio programma.

Sono però di fronte ad una tabella che attualmente corrisponde alla Mesi.List (ComboBox) contenuta nella Form1, per cui fino ad ora ho sempre fatto riferimento alla Lista tramite istruzioni del tipo
Codice: [Seleziona]
Form1.Mesi.List[i_Mese]
Adesso la Form1 viene richiamata con la metodologia "Metodi nascosti" e l'istruzione appena citata non funziona più, perciò ho bisogno di costituire un'array specifico che prima non mi serviva e, piuttosto, che crearlo come variabile globale, vorrei definirlo dentro la Form FMain con
Codice: gambas [Seleziona]
STATIC PUBLIC TabMesi AS String[12] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]

Così facendo potrei interrogare sempre l'array con la mia vecchia istruzione dopo averlas adeguata --> FMain.Mesi[i_Mese] ed eviterei una vera e propria variabile globale.

Secondo la vostra maggiore esperienza, riesco nell'intento, oppure esiste un'altro procedimento più efficace ed a risparmio energetico?  ;D
Ciao
« Ultima modifica: 01 Ottobre 2010, 22:33:56 da Picavbg »
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #1 il: 21 Settembre 2010, 17:07:45 »
La tabella specificata, in definitiva credo non cambi mai... Detto questo puoi trasformarla in costante, aggiungendo appunto la clausola CONST.

Ma, a parte questo, l'uso di quella variabile in definitiva non cambia, basta chiamarla nel giusto modo, ovvero <Nome classe>.<Variabile>, che è poi convetualmente uguale al chiare una proprietà di un oggetto.

Vedo di chiarire il concetto.

L'uso di variabili globali, oltre che deleterio come hai descritto (ma ci sono altre implicazioni), è pure fuori luogo, visto che il linguaggio permette di gestire la memoria in modo molto dinamico.

La tua dichiarazione, come sopra detto, non cambia, se questa è dichiara all'interno di una classe appropriata, e potrà essere utilizzata allo stesso modo che se fosse dichiarata all'interno di un modulo che, ricordo, è comunque una classe nella struttura Gambas, solo che è per definizione statica.

Una volta che la variabile assume la forma di costante, questa non può essere referenziata ovvero, non c'è bisogno di creare la classe per potervi accedere, perchè creata automaticamente all'avvio dell'applicazione (è un elemento statico, ovvero sempre presente in memoria).

Se, al contrario, la definisci come proprietà di una classe, allora sei obbligato a creare la classe stessa, prima di poter accedere a quella variabile.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #2 il: 22 Settembre 2010, 15:43:56 »
La tabella specificata, in definitiva credo non cambi mai... Detto questo puoi trasformarla in costante, aggiungendo appunto la clausola CONST.
...............................
Una volta che la variabile assume la forma di costante, questa non può essere referenziata ovvero, non c'è bisogno di creare la classe per potervi accedere, perchè creata automaticamente all'avvio dell'applicazione (è un elemento statico, ovvero sempre presente in memoria).

Dal nuovo spunto che mi hai dato ho ripreso la mia variabile definita in FMain:
Codice: [Seleziona]
STATIC PUBLIC TabMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
provata e funzionante, e l'ho modificata così:
Codice: gambas [Seleziona]
PUBLIC CONST TabMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]

ma evidentemente non ho capito, perché così come l'ho scritta fornisce l'errore
Citazione
Bad constant type alla line xx in FMain.class
, come se Gambas non accetti una constante stringa strutturata sotto forma di array.

Ho anche cercato un esempio simile nel Forum, nel Beginner Guide, nel wiki, ma non sono stato capace di trovarlo. Eppure la modifica mi sembrava semplice. Dove ho sbagliato?
Ciao
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #3 il: 22 Settembre 2010, 16:08:15 »
Intanto modificala aggiungendo STATIC all'inizio, altrimenti ne ricrea una nuova ad ogni nuovo oggetto, e la cosa non è ottimale...

Poi, attenzione ai ritorni a capo, se ce ne sono, perchè Gambas2 non digerisce definizioni di proprietà che ritornano a capo nella dichiarazione.

Altra alternativa sarebbe quella di creare un motodo statico, ma forse ti complico la vita.


COmunque, ora non posso verificare il problema, perchè non ho Gambas a disposizione. Stasera potrò risponderti...

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #4 il: 22 Settembre 2010, 16:26:15 »
In realtà dovevo avviare la VM con Linux...  :P

Devi perdonarmi, ma era una cosa ormai che avevo dimenticato, e avevo utilizzato altri modi per farlo...

Comunque, la clausola CONST in realtà si può usare solo con variabili semplice (es. String, Integer, ecc.) e non con gli array. Questa è una limitazione di gambas2, che spero abbiano corretto nella 3.

Ad ogni modo, ripensando alla tua modifica, in realtà parti da un concetto non totalmente corretto.
E' corretto pensare che un determinato dato "fisso", che faccia comunque parte a un determinato oggetto o classe, debba possibilmente essere inserito nel giusto posto, ovvero la classe stesso. E' anche vero che in questo caso specifico, in realtà tu stai definendo una cosa che praticamente non cambia mai.
Però, e dico però, questo non esclude che tu possa comunque inserirla nella classe appena creata, come hai fatto, ma dato il problema di cui sopra, sei costretto ad non usare CONST. Però, e continuo a dire però, ed è una cosa che faccio di norma, si può creare un'apposito metodo statico, che ritorni un array contenente i dati di cui sopra (i nomi dei mesi).
Il risultato non cambia, nel senso che il metodo statico ritornerebbe comunque una array (che puoi anche rendere NON modificabile), e tenere il metodo nella classe in cui hai deciso di inserirlo.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #5 il: 22 Settembre 2010, 18:48:05 »
Scusami, ma non ti capisco, o meglio: non capisco cosa intendi per:
Citazione
si può creare un'apposito metodo statico, che ritorni un array contenente i dati di cui sopra (i nomi dei mesi).
   :-\
Forse, se mi potessi fornire un esempio (possibilmente dettagliato), potrei riuscire a capire.
 :(

:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #6 il: 23 Settembre 2010, 10:53:13 »
Ti faccio un esempio al volo, dato che ho sempre delle difficoltà a reperirti codice funzionante dal posto in cui sono...

Codice: [Seleziona]
STATIC PUBLIC FUNCTION TabMesi() AS String[]
  DIM tbMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
  RETURN tbMesi
END

Dato che la funzione TabMesi è dichiarata statica, puoi chiamarla direttamente, anche se è inclusa in una classe:
Codice: [Seleziona]
<classe>.TabMesi()
quindi allo stesso modo di un modulo.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #7 il: 25 Settembre 2010, 23:50:01 »
Ti faccio un esempio al volo, dato che ho sempre delle difficoltà a reperirti codice funzionante dal posto in cui sono...
Codice: [Seleziona]
STATIC PUBLIC FUNCTION TabMesi() AS String[]
  DIM tbMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
  RETURN tbMesi
END
Dato che la funzione TabMesi è dichiarata statica, puoi chiamarla direttamente, anche se è inclusa in una classe:
Codice: [Seleziona]
<classe>.TabMesi()
quindi allo stesso modo di un modulo.

Mmmmmmmh  :danger:
Se ho finalmente capito, tu dici: dichiaro un modulo contenente la funzione public in cui costruisco la famosa stringa TabMesi, valorizzata coi mesi in chiaro:
' Gambas class file
Codice: gambas [Seleziona]
'----------------------------------- Modulo TableMesi --------------------------------------------------------------------------------------------------------------------------------------------------
STATIC PUBLIC FUNCTION TabMesi() AS String[]
  DIM tbMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
  RETURN tbMesi
END

.; poi per richiamare uno degli elementi, per Es. "Settembre", in qualsiasi procedura del progetto, scrivo:
Codice: gambas [Seleziona]
Mese = TableMesi.TabMesi[8]
print Mese


Però non discosta molto dal mio utilizzo attuale:
Codice: [Seleziona]
STATIC PUBLIC $TabMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
che richiamo con:
Codice: [Seleziona]
$Mese = FMain.$TabMesi[8]
Print $Mese

Il modulo é effettivamente sempre presente in memoria, ma il mio Fmain che utilizzo per richiamare tutte le Form del Progetto con i vari richiami di tipo showmodal, tramite metodo _new, credo che sia sempre in memoria.
O no ?  :-[

Aggiungo poi un'altra riflessione: La dichiarazione di una variabile globale é Public, mentre quella dichiarata nel modulo "TableMesi" é DIM, però quest'ultima appartiene ad una Function di tipo STATIC PUBLIC. Ma in pratica non occupa sempre una posizione di memoria, così come una variabile globale?

Insomma: Non é mollica, ma briciola. :)
Ciao
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #8 il: 27 Settembre 2010, 13:03:44 »
Sai qual'è il problema?

Questa piccola chiacchierata si stà basando su una base non propriamente corretta, ovvero su un caso che ha poco senso nel concetto generale della programmazione ad oggetti.

Come ti avevo anche accennato, per il caso specifico ha poca importanza se sia incluso in un modulo o in una classe, perchè trattasi di dati appunto statici, che non cambiano nel tempo. Questo a meno che tu non abbia voglia di implementare un progetto multilanguage...

Le variabile che, come dive anche il nome sono "variabili", hanno un determinato scopo, ovvero quello di contenere dati mutabili nel tempo.
Nella vecchia programmazione, come nella nuova ad oggetti, questi elementi sono basilari, non si può farne a meno. E' come avere un cervello senza memoria (dove appoggi i dati che sti elaborando?)...

Piccola nota:
nell'ultimo esempio che ti ho fatto, non puoi richiamare un elemento dell'array in quel modo. Dato che l'array è restituito da un metodo, devi prima chiamare il metodo "<classe>.TabMesi()", indi l'indice "<classe>.TabMesi()
  • ".

In teoria potresti anche implementare un parametro "indice", cda utilizzare per farti ritorna un determinato mese, e non tutta la lista.

Offline andy60

  • Senatore Gambero
  • ******
  • Post: 1.255
    • Mostra profilo
    • https://www.linkedin.com/in/andbertini
Re: Diamo un taglio alle variabili globali
« Risposta #9 il: 28 Settembre 2010, 22:06:43 »
Sulle variabili globali mi sento di fare una considerazione: premesso che non sono un ultraesperto programmatore, ma se devo passare dei dati da una form all'altra non riesco a non usare variabili globali. Faccio un esempio: attraverso la form ricette richiamo la form alimenti e seleziono un alimento selezionato. L'id selezionato serve nella form ricette, non trovo altro modo x passare i dati se non attraverso una variabile globale. Con i metodi nascosti di cui parlate...ancora non sono alla mia portata...sto studiando l'esempio di mdxxxx :hard: sui metodi nascosti
« Ultima modifica: 29 Settembre 2010, 00:03:46 da andy60 »

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #10 il: 29 Settembre 2010, 00:25:12 »
Ciao andy!

Come per picav, il discorso è perchè ancora non vi è ben chiara una cosa... leggete!!!

Scherzo, ma sono anche serio... il tuo problema è che Form accetta già di suo un parametro opzionale, ovvero un oggetto, un container.

Mi spiego meglio...

Considera la Form una specie di Panel, e lo è davvero, che può essere inserita in un'altro contenitore. La Form stessa è un contenitore, ma in ogni caso è derivata dall'oggetto Window, da cui deriva proprio questo parametro opzionale.

Dato che è opzionale, se non lo passi nella creazione della Form, viene considerata NULL, ma comunque è come se glielo avessi passato.
Se tu crei una Form, su cui definisci un tuo parametro, questo si aggiunge a quello esistente e, per la logica implementata in Gambas, la sequenza con cui devi passare i parametri è descritta nella documentazione, ovvero devi prima iniziare con i parametri della classe derivata più bassa (la tua), seguiti dai parametri della classe superiore, e così via.

Ad ogni modo, il mio discorso sicuramente vi avrà portato fuori strada, perchè nel tuo caso specifico, il parametro che tu passi alla tua Form, in teoria deve essere letto dalla "tua" Form, e non dalla classe superiore (la Window, tanto per intenderci...).
Quello che devi verificare, è che la "tua" Form, abbia il metodo _new(), con il "tuo" parametro. Se questo non c'è, è inutile che glielo passi, perchè se lo prenderà la classe superiore, che si aspetta invece un tipo di dato diverso, è quindi ti dà errore.

Si è fatto un pò tardi, e sono pure abbastanza malmesso (con questo tempaccio...), quindi spero che abbia scritto cose comprensibili...  ;D

Usare variabili globali è sicuramente fattibile, e infatti funziona, ma funziona fichè hai un piccolo progetto, che ti permette di tener sotto controllo tutte le fasi logiche. Ammettiamo per caso, di avere un grosso progetto, in cui sono definiti un massiccio numero di componenti (oggetti, moduli, e via dicendo), e tutti si alimentano con i dati globali, e per necessità questi dati devono poter essere manipolati, ogni classe può, in definitiva, aggire su questi, ignaro di quello che stanno facendo gli altri. Metti conto dei processi non sequenziali, che lavorano in modo asincrono... coem gestisci le eventuali e possibilissime sovrascritture? Come riesci a capire se il dato che ti aspetti, non sia nel frattempo stato modificato da un altro processo?

Il passaggio di dati, attraverso le varie funzioni che compongono un programma, non è logica uscita fuori con la programmazione ad oggetti, ma per l'esigenza di avere il maggior controllo possibile sulle informazioni veicolate, senza interferenze.

Certo, avere un'area pubblica, in cui posizionare i nostri dati, rende la vita molto più semplice. Ma questo solo apparentemente, e solo inizialmente. Quando ci si accorge dei problemi che poi questo comporta, il discorso assume un'aspetto diverso.

Quello che infine voglio dire, è che tutti inizialmente compiono questo errore di valutazione, ci siamo passati tutti, ma questo è dipeso solo dalla nostra scarsa conoscenza della materia. Come hai anche tu sottolineato, andy, non avendo capito alcuni concetti, ovviamente hai scelto la strada apparentemente più alla portata, il che mi pare anche normale.
La programmazione si basa sull'esperienza, ma questa bisogna farla provando e riprovando, chiedendo lumi, e cercando di capire il perchè e il percome una cosa debba funzionare in un modo piuttosto che in un'altro, quali strumenti ho a disposizione, provare ad implementarli, e via dicendo. La programmazione NON è una scienza esatta... ;)

Scusate, mi sono dilungato un pò troppo...  :-\

Offline andy60

  • Senatore Gambero
  • ******
  • Post: 1.255
    • Mostra profilo
    • https://www.linkedin.com/in/andbertini
Re: Diamo un taglio alle variabili globali
« Risposta #11 il: 29 Settembre 2010, 07:55:15 »
Grazie per la sempre puntuale, precisa e piena di spunti, risposta, sono riuscito a far funzionare il tuo codice in myZone e in effetti ci sto prendendo gusto.  :2birre:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #12 il: 29 Settembre 2010, 13:03:46 »
Grazie per la sempre puntuale, precisa e piena di spunti, risposta, sono riuscito a far funzionare il tuo codice in myZone e in effetti ci sto prendendo gusto.  :2birre:

Complimenti! Stavo per mandarti un esempio dal mio programma, perché, secondo me, a volte le parole non bastano per chiarire bene un concetto; allora occorre aggiungere un pò di materiale pratico, però una volta che hai risolto e, soprattutto, compreso, non é più necessario.

Chiedo scusa a md9327 per la precisazione appena fatta, ma, con essa, non voglio minimamente criticare le sue spiegazioni, sempre ricche di dettagli di logica meccanicistica di Gambas, e non solo.
Purtroppo, però, la limitata conoscenza che uno come me può avere del "contenitore massimo", cioé di Gambas, non ne permette la corretta e/o completa comprensione.  :D

E siccome: Tutto é bene quel che finiosce bene, mi associo al  :2birre:
Ciao.
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: Diamo un taglio alle variabili globali
« Risposta #13 il: 29 Settembre 2010, 14:36:46 »
Non me la prendo sicuramente, anzi, siamo qui per imparare tutti, anche io... (e non poco...)

Al contrario, io spero di non aver offeso magari qualcuno, con le mie parole. A volte, per chiarire dei concetti, devo passare alle maniere un pò più dure, ma non sicuramente a causa dell'interlocutore, ma solamente perchè potrebbero risultare più chiare.

Inoltre, spesso scrivo la sera tardi, dopo qualche oretta passata al pc, e data l'ora picciola, a volte mi si imbrogliano le idee...  :rolleyes:  ;D

Ma, a parte questo, sono contento che andy abbia risolto subito dietro al mio discorso, il che vuol dire che non è proprio così male...  ;D
E, comunque, sono qui per cercare di aiutare, per cui caro picav(ecc. ecc.)  ;D , non farti scrupoli con le domande. Ognuno assorbe a modo suo, e forse devo trovare altri metodi per farti comprendere il giochetto (per modo di dire, ovviamente...).
Detto questo, visto che hai accennato ad un esempio, invialo e lo vediamo...  :ok:

Offline andy60

  • Senatore Gambero
  • ******
  • Post: 1.255
    • Mostra profilo
    • https://www.linkedin.com/in/andbertini
Re: Diamo un taglio alle variabili globali
« Risposta #14 il: 29 Settembre 2010, 15:42:28 »
Non me la prendo sicuramente, anzi, siamo qui per imparare tutti, anche io... (e non poco...)

Al contrario, io spero di non aver offeso magari qualcuno, con le mie parole. A volte, per chiarire dei concetti, devo passare alle maniere un pò più dure, ma non sicuramente a causa dell'interlocutore, ma solamente perchè potrebbero risultare più chiare.

Inoltre, spesso scrivo la sera tardi, dopo qualche oretta passata al pc, e data l'ora picciola, a volte mi si imbrogliano le idee...  :rolleyes:  ;D

Ma, a parte questo, sono contento che andy abbia risolto subito dietro al mio discorso, il che vuol dire che non è proprio così male...  ;D
E, comunque, sono qui per cercare di aiutare, per cui caro picav(ecc. ecc.)  ;D , non farti scrupoli con le domande. Ognuno assorbe a modo suo, e forse devo trovare altri metodi per farti comprendere il giochetto (per modo di dire, ovviamente...).
Detto questo, visto che hai accennato ad un esempio, invialo e lo vediamo...  :ok:

troppo forte sto forum, onorato di far parte della Comunità :2birre: