Italian [B4A] Il nome di una variabile non può coincidere con quello di una routine

Discussion in 'Italian Forum' started by Giorgio Brausi, Nov 9, 2018 at 8:57 AM.

  1. Giorgio Brausi

    Giorgio Brausi Member Licensed User

    Salve,

    ho aperto il progetto di esempio MyFirstProgram, nel Designer ho aggiunto un nuovo EditText (EditText1) e dal menu Strumenti -> Genera membri ho generato due membri: TextChanged e EnterPressed.

    Code:
    Sub EditText1_TextChanged (Old As String, New As String)
      
    End Sub

    Sub EditText1_EnterPressed
      
    End Sub
    Poi ho aggiunto nella Sub Globals la dichiarazione
    Code:
    Private EditText1 As EditText

    L'EnterPressed è ok.
    Il TextChanged invece appare sottolineato in rosso ed il messaggio nel tooltip mi comunica:
    Il nome di una variabile non può coincidere con quello di una routine
    e non riesco a capire come mai.

    Questo è l'output della compilazione:

    B4A Versione: 8.50
    Analisi del Codice. (0.00s)
    Building folders structure. (0.02s)
    Compilazione del codice. Error
    Errore nella compilazione del programma.
    Descrizione dell'errore: Il nome di una variabile non può coincidere con quello di una routine. (new).
    Errore nella linea: 79
    Sub EditText1_TextChanged (Old As String, New As String)
    Word: edittext1_textchanged

    Ho provato diverse volte ad eliminare, chiudere il progetto, riaprirlo e ricreare ma si verifica sempre lo stesso problema.
    Inizialmente, sempre con lo stesso progetto, questo non accadeva.

    Cosa può essere?

    EDIT
    Facendo una ricerca trai files della cartella MyFirstProgram ho trovato nel file \SourceCode\MyFirstProgram\Objects\shell\bin\classes\b4a\MyFirstProgram1\main_subs_0.class la stringa

    _edittext1

    Ho l'impressione che c'entri qualcosa.
    Se ho ragione, posso cancellare il file?
    Ma poi perché nella cartella \classes\ ho due cartelle MyFirsProgram e MyFirsProgram1 ?
     
    Last edited: Nov 9, 2018 at 9:09 AM
  2. LucaMs

    LucaMs Expert Licensed User

    Mah, strano. Comunque, nello stesso modo in cui hai creato le routine-evento puoi creare la dichiarazione della variabile, ovvero da menu.
     
    Last edited: Nov 9, 2018 at 9:42 AM
  3. klaus

    klaus Expert Licensed User

    This sounds very strange.
    Can you upload your project as a zip file, so we can see what exactly you have done and how.

    upload_2018-11-9_10-28-47.png

    You can also close the IDE, delete the Objects folder and delete this file MyFirstProgram.b4a.meta and reload the project in the IDE.
     
  4. Giorgio Brausi

    Giorgio Brausi Member Licensed User

    Unfortunately I've deleted previous project.
    I unpacked the original project again and again create the EditText, getting the same problem.

    [​IMG]
     

    Attached Files:

  5. LucaMs

    LucaMs Expert Licensed User

    You created a Sub New. Change its name.
     
  6. Giorgio Brausi

    Giorgio Brausi Member Licensed User

    Sorry but I don't understand...
    The Subs were created by B4A Designer: Tools->Generate Members menu don't by me.
     
  7. PCastagnetti

    PCastagnetti Member Licensed User

    Hai una sub New che coincide con il parametro New dell'evento textchanged.
    Rinomina Sub New in New2 ( e le relative chiamate)
    Code:
    Sub New2
        Number1 = 
    Rnd(110)            ' Generates a random number between 1 and 9
        Number2 = Rnd(110)            ' Generates a random number between 1 and 9
        lblNumber1.Text = Number1        ' Displays Number1 in label lblNumber1
        lblNumber2.Text = Number2        ' Displays Number2 in label lblNumber2
        lblComments.Text = "Enter the result" & CRLF & "and click on OK"
        edtResult.Text = 
    ""            ' Sets edtResult.Text to empty
    End Sub
     
    Giorgio Brausi, klaus and Star-Dust like this.
  8. LucaMs

    LucaMs Expert Licensed User

    Perché poi ho scritto in inglese? :p
     
  9. Giorgio Brausi

    Giorgio Brausi Member Licensed User

    Probabilmente a seguito dell'intervento di Klaus :D

    Hai proprio ragione. Il problema è quello.
    Però onestamente, questo mi sconcerta non poco!!!
    Un parametro (in questo caso New As String) indicato nella firma di una routine dovrebbe essere locale.
    Il fatto che sia considerato pubblico mi lascia molto molto perplesso...

    In 30 anni che sviluppo software in vari linguaggi non mi era mia accaduto una cosa del genere (fino ad ora). Assurdo!
    Francamente, lo considero un bug del linguaggio B4A.


    In ogni caso Grazie infinite. :)
     
    Last edited: Nov 9, 2018 at 12:52 PM
    LucaMs likes this.
  10. MarcoRome

    MarcoRome Expert Licensed User

  11. Star-Dust

    Star-Dust Expert Licensed User

    Infatti il parametro è locale, mentre la SUB NEW è pubblica. E' la sub che essendo pubblica all'interno di EditText1_TextChanged va in conflitto con la variabile Locale
    potevi anche fare così e funzionava lo stesso:
    Code:
    Sub EditText1_TextChanged (OldText As String, NewText As String)
     
    End Sub
     
  12. Giorgio Brausi

    Giorgio Brausi Member Licensed User

    Ma se il parametro è locale come fa an andare in conflitto con una ruotine esterna, e viceversa, pur se dichiarata pubblica?
    Non ha senso.
    Questo va in conflitto con le regole di incapsulamento della programmazione ad oggetti.

    In VB.NET questo codice viene eseguito senza problemi:
    Code:
    Public Class Form1
        Function MyVar(ByVal pParameter 
    As Integer) As String
            
    If pParameter = 1 Then
                
    Return "First"
            
    Else
                
    Return "Last"
            
    End If
        
    End Function
        
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            MessageBox.Show(MyVar(
    1)) ' mostra "First"
        End Sub

        
    Private Sub EditText1_TextChanged(sender As Object, MyVar As EventArgs) Handles EditText1.TextChanged
            MessageBox.Show(MyVar.ToString) 
    ' mostra: "System.EventArgs"
        End Sub
    End Class
    Ma stessa cosa in C#, e persino in VB6.
     
  13. Star-Dust

    Star-Dust Expert Licensed User

    Secondo me ti sbagli. Se chiamo New all'interno di EditText1_TextChanged, mi potrei riferire alla variabile locale ma potrei voler richiamare la sub pubblica all'interno di TextChanged.

    In VB6, con MyVar indichi la variabile locale ma non potrai richiamare la funzione che ne porta lo stesso nome all'interno della EditText1_TextChanged. Quindi se lo volessi fare (richiamare la sub MyVar), dovresti sempre cambiare nome a una delle due.

    L'incapsulamento non mi sembra che ci entri molto in questo discorso.

    Comunque importante che hai trovato la risposta alla tua domanda e puoi proseguire.
     
    Last edited: Nov 9, 2018 at 4:45 PM
  14. LucaMs

    LucaMs Expert Licensed User

    In B4A le variabili sono alquanto strane, in effetti. Se dichiari un array a livello globale, diciamo di 10 elementi, poi ne dichiari uno locale, in una routine, di 20 elementi, in realtà hai modificato quello globale, che sarà di 20 elementi (questo senza il Redim di VB.Net e tantomeno il Preserve).
     
  15. Giorgio Brausi

    Giorgio Brausi Member Licensed User

    Addirittura? Andiamo bene... :confused:

    @Star-Dust Ecco cosa c'entra incapsulamento. Quindi c'entra, eccome se centra.
    Comunque hai detto bene, la risposta l'ho trovata, dovrò agire di conseguenza.

    Grazie a tutti. :D
     
  16. LucaMs

    LucaMs Expert Licensed User

    Non ricordo VB6 ma ti ha dismostrato che in VB.Net puoi farlo.
     
  17. LucaMs

    LucaMs Expert Licensed User

    upload_2018-11-9_18-6-18.png
     
  18. MarcoRome

    MarcoRome Expert Licensed User

    Nessun errore e nessuna stranezza.
    Come dice Erel QUI

    Infatti nella "Visibilità" delle Variabili Globali:

    LEGGI QUI

    Quindi il buon Erel per evitare "errori" e tagliare la testa al toro ha inserito questo check ( ben fatto ). E' più comodo avere un messaggio dato nel check "Variable name cannot be the same as sub name" che incorrere in un eventuale e "subdolo" errore.
     
    Star-Dust likes this.
  19. udg

    udg Expert Licensed User

    Scusate, dico la mia con riferimento in particolare ai post #12 e #13.
    In generale dovrebbe essere possibile, senza alcuna confusione di sorta da parte del compilatore, utilizzare per una variabile lo stesso identificativo utilizzato per il nome di una funzione. La ratio sta nel fatto che il compilatore dovrebbe comprendere, senza alcuna difficoltà, che si trova nella parte dichiarativa del metodo e quindi ovviamente l'identificativo è una variabile locale. Mi spiego con l'esempio di cui sopra:

    In questo caso "New" (in TextChanged) è necessariamente la dichiarazione di una variabile locale e non la chiamata ad una funzione di nome New. E non vedo come il compilatore possa confondersi.
    Se nel corpo di TextChanged avessi un New = "abc" teoricamente il compilatore potrebbe essere confuso e non sapere se mi sto riferendo alla variabile locale New (ed in tal caso l'assegnazione è ok) oppure sto chiamando in modo errato la funzione New (e quindi avvisarmi con warning o errore).
    La cosa si risolve facilmente differenziando tra:
    New = "abc" <-- new variabile locale
    <module name>.New(58) <-- chiamata a funzione di nome New definita nel modulo X

    Ho utilizzato impropriamente il termine funzione per la public New laddove sarebbe stato più corretto parlare di procedura (le mie radici sono nel Pascal) o metodo.

    E se a runtime volessimo (corretti i tipi e le definizioni in modo opportuno) chiamare TextChanged passando come secondo parametro il risultato della funzione?
    Scriveremmo TextChanged("old1", Main.New(77)), ancora una volta senza possibilità di confusione.

    Ad ogni modo, direi che le spiegazioni fornite da Marco siano valide e condivisibili. Dobbiamo ricordare che B4X è un linguaggio di suo, non è Pascal, C. C#, VB etc etc e quindi è giusto che abbia le sue regole. Come abbiamo accettato quelle degli altri, ora possiamo serenamente uniformarci a quelle di B4x.

    ps: lasciate che in questa occasione io possa esprimere il mio ringraziamento al prof. Niklaus Wirth per avere ideato, tra le altre cose, il linguaggio Pascal, il mio primo vero amore (informatico..lo preciso per @LucaMs, che non si sa mai..ehehe)
     
  20. LucaMs

    LucaMs Expert Licensed User

    Più che una stranezza è una differenza rispetto ad altri linguaggi, nei quali puoi avere una variabile locale con nome uguale ad una globale.

    Poi, magari, meglio così.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice