Italian domanda da Principiante sulle SUBroutine

Ciao amici, venendo dal basic, mi trovo in difficoltà a gestire subroutine comuni a più moduli, in pratica quelle definite Public nel vecchio basic.

In una app b4x ho moduli nei quali ho ripetuto le stesse subroutine, ovvio non è una cosa buona.
Vorrei quindi raggrupparle in un punto unico e richiamarle dai vari moduli, questo però comporta di non poterle più richiamare sermplicemente con
il loro nome ma solo attraverso il comando

x = CallSub2(Main, "AddEm", z)

anzichè

x=AddEm(z)

lo trovo assai complicato a tal punto di preferire di ricopiarmi le subroutine ogni nuovo modulo.
Forse ho capito male?
C'è un modo per condensare le sub riutilizzabili nel progetto alla stegua di una libreria?
 

Elric

Well-Known Member
Licensed User
Ciao Principiante.

Ti rispondo da principiante; magari passa qualcuno più esperto di me che ti dà una risposta più corretta.

Se ho capito bene la domanda (e per me non è molto chiara) tu vorresti avere un modulo dove stipare tutte le subroutine replicabili.

Se così è, crei un modulo di classe, che qui chiamerò "clsArith". Ipotizzo, che in clsArith hai le funzioni delle operazioni aritmetiche, ad esempio la somma:
B4X:
Public Sub Sum (a as int, b as int) as Resumable sub

Return a + b

End Sub

Quindi, nel tuo modulo "Main" e in ogni altro modulo in cui vuoi richiamare queste sub devi:
* dichiararlo:
B4X:
Sub Class_Globals
(...)
Private cArith As clsArith
(...)
End Sub

* inizializzarlo (io uso le B4XPage)
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    cArith.Initialize
End Sub

e quindi puoi richiamarle:
B4X:
Private Sub Button1_Click
    Label1.Text = cArith.Sum(1, 2)
End Sub
 
Last edited:

drgottjr

Expert
Licensed User
Longtime User
oppure:
ci sono 4 modi di condividere codice:

1) copiando a mano da un progetto al otro
2) creando una classe con le funzioni che si condividono nelli progetti
3) creando un modulo detto "codice" che sirve lo stesso proposito di una classe
4) creando una libreria

per 2, 3 e 4, il modo di "chiamare" una funzione e lo stesso:
x = classe.AddEm(z)
x = modulo_codice.AddEm(z)
x = libreria.AddEm(z)

si include la classe, il modulo o la libreria come indicato nella imagine allegata
 

Attachments

  • PXL_20211208_151727385.jpg
    PXL_20211208_151727385.jpg
    106.6 KB · Views: 98
Ottime informazioni. Mi sfuggiva il fatto di dover inizializzare la classe o modulo.
Purtroppo è diverso dal mio linguaggio di provenienza il "basic", li era sufficente dichiarare public una subroutine per utilizzarla subito in tutti i moduli di tutto il progetto.

Mi chiedo se arebbe sbagliato introdurre un nuovo tipo di modulo ad esempio public_module nel quale inserire subroutine che agirebbero come se fossere scritte o copiate automaticamente in ogni modulo dove vi è una chiamata a quella subroutine? Questo eviterebbe di dove istanziare la classe comune in ogni modulo.
Però se non è stato fatto forse il motivo è quello di avere un codice più rigoroso e coerente, difatti B4X non è basic.
Se ci sono commenti sono graditi.
 

LucaMs

Expert
Licensed User
Longtime User
Ciao Principiante.

Ti rispondo da principiante; magari passa qualcuno più esperto di me che ti dà una risposta più corretta.

Se ho capito bene la domanda (e per me non è molto chiara) tu vorresti avere un modulo dove stipare tutte le subroutine replicabili.

Se così è, crei un modulo di classe, che qui chiamerò "clsArith". Ipotizzo, che in clsArith hai le funzioni delle operazioni aritmetiche, ad esempio la somma:
B4X:
Public Sub Sum (a as int, b as int) as Resumable sub

Return a + b

End Sub

Quindi, nel tuo modulo "Main" e in ogni altro modulo in cui vuoi richiamare queste sub devi:
* dichiararlo:
B4X:
Sub Class_Globals
(...)
Private cArith As clsArith
(...)
End Sub

* inizializzarlo (io uso le B4XPage)
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
Root.LoadLayout("MainPage")
cArith.Initialize
End Sub

e quindi puoi richiamarle:
B4X:
Private Sub Button1_Click
    Label1.Text = cArith.Sum(1, 2)
End Sub
Non è certo necessario, in quel caso, che la la routine Sum sia una Resumable (e quindi che restituisca ResumableSub).
Non è nemmeno necessario creare delle classi, anche se molto spesso sono utili. Chiedeva di routine e moduli di codice. Basta premettere il nome del modulo di codice, il punto e il nome della routine.

Es.

Modulo di codice
modMath
Public Sub Sum(...

e da qualunque altro punto del progetto:
Somma = modMath.Sum(...
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
oppure:
ci sono 4 modi di condividere codice:

1) copiando a mano da un progetto al otro
2) creando una classe con le funzioni che si condividono nelli progetti
3) creando un modulo detto "codice" che sirve lo stesso proposito di una classe
4) creando una libreria

per 2, 3 e 4, il modo di "chiamare" una funzione e lo stesso:
x = classe.AddEm(z)
x = modulo_codice.AddEm(z)
x = libreria.AddEm(z)

si include la classe, il modulo o la libreria come indicato nella imagine allegata
Troppo complicato e sintetico, per un principiante ;)
 

Elric

Well-Known Member
Licensed User
Non è certo necessario, in quel caso, che la la routine Sum sia una Resumable (e quindi che restituisca ResumableSub).
Si, quel "resumable sub" lo avevo messo inizialmente insieme al wait for; poi ho eliminato il wait for ma non il resumable.
Non è nemmeno necessario creare delle classi, anche se molto spesso sono utili. Chiedeva di routine e moduli di codice. Basta premettere il nome del modulo di codice, il punto e il nome della routine.

Es.

Modulo di codice
modMath
Public Sub Sum(...

e da qualunque altro punto del progetto:
Somma = modMath.Sub(...
Ed ecco arrivato chi ne sa (a stra-pacchi) più di me! Metodo molto più semplice del mio!
 

drgottjr

Expert
Licensed User
Longtime User
Troppo complicato e sintetico, per un principiante ;)
a Principiante, sembla che gli piaceva una risposta complicata e sintetica. ne ho molte altre simili ;)
 

LucaMs

Expert
Licensed User
Longtime User
Mi sfuggiva il fatto di dover inizializzare la classe o modulo.
Il modulo di codice non va inizializzato, esiste sempre e le sue routine sono sempre disponibili.

Il modulo di classe, invece, non si usa e non si può usare direttamente, serve a creare oggetti, i quali espongono le routine (e non solo) che poi tu puoi utilizzare.
https://www.b4x.com/android/forum/threads/classes-are-soon-coming.18395/#content

Ripeto che le classi sono utilissime (di solito si usano per creare oggetti simili ma non uguali, come ad esempio 10 automobili create dalla classe Automobile, ma anche per fornire funzioni/funzionalità, nel qual caso conviene crearne librerie) ma anche i moduli di codice possono essere comodi, proprio perché esistono senza bisogno di dichiararli e inizializzarli e le loro routine (funzioni) sono disponibili immediatamente e da qualunque punto del progetto.
 
Non è certo necessario, in quel caso, che la la routine Sum sia una Resumable (e quindi che restituisca ResumableSub).
Non è nemmeno necessario creare delle classi, anche se molto spesso sono utili. Chiedeva di routine e moduli di codice. Basta premettere il nome del modulo di codice, il punto e il nome della routine.

Es.

Modulo di codice
modMath
Public Sub Sum(...

e da qualunque altro punto del progetto:
Somma = modMath.Sub(...
ESATTAMENTE quello che cercavo , ma avendo provato a farlo prima di scrivervi, non mi era riuscito, ma grazie a Te LucaMs ho riprovato avendo la certezza questa volta , che doveva essere possibile e difatti così è stato!
Quindi è scontato che ho commesso qualche errore che mi ha depistato e mi ha fatto ricorrere al vs. aiuto, in mancanza del quale sarei rimasto impantanato.
 
Top