It is currently 15 September 2019, 13:28 Advanced search

parametri output... ma funzionano??

Domande e risposte su come utilizzare Instant Developer Foundation al meglio

parametri output... ma funzionano??

Postby theguru » 12 September 2019, 16:12

Scusate lo sfogo, ma ogni volta che mi trovo a costretto a passare parametri per riferimento ad una funzione, vengono fuori malfunzionamenti a pioggia davvero destabilizzanti.

Esempio: è normale che se io ho una funzione definita in questo modo:
Screen Shot 2019-09-12 at 17.44.32.png
Screen Shot 2019-09-12 at 17.44.32.png (15.61 KiB) Viewed 132 times

e la chiamo semplicemente così:
Screen Shot 2019-09-12 at 17.20.42.png
Screen Shot 2019-09-12 at 17.20.42.png (9.22 KiB) Viewed 132 times

I 4 parametri di output alla fine dell'elaborazione non abbiano il valore atteso?
Ma vengono o non vengono passati per riferimento?
e perché se modifico la chiamata di prima in questo modo:
Screen Shot 2019-09-12 at 17.50.04.png
Screen Shot 2019-09-12 at 17.50.04.png (27.65 KiB) Viewed 132 times
allora tutto si mette a funzionare?
Quindi le variabili di un ciclo foreach me le passate per valore, e quelle definite localmente me le passate per riferimento? anche se la funzione è la stessa, definita allo stesso modo?
E perché ho un problema analogo anche con le proprietà delle classi?
E perché se ho una funzione con parametri misti (output e non output) anche le variabili passate per valore (ai parametri NON output) assumono il valore assegnato dentro la funzione, come se fossero state passate per riferimento?
Tutto quanto sopra mi costringe a fare un lavoro di.. disaccoppiamento dei parametri, utilizzando variabili come nel caso dell'immagine sopra. Oppure andare alla cieca, non sapendo come si comporterà il framwork.
Ma sopratutto, tutto quanto sopra è stato pensato per funzionare in questo modo, o si tratta di bug?
C'è una pagina della documentazione o della guida dove si faccia luce su tutto ciò?
Abbiate pazienza, ma qui non si parla di una strana funzione di alto livello, che se non funziona pazienza, questi discorsi riguradano concetti che stanno alla base di ogni linguaggio di programmazione, ed ogni volta mi ci incasino.
Peace and love a tutti, come sempre.
User avatar
theguru
 
Posts: 645
Joined: 29 January 2014, 13:01

Re: parametri output... ma funzionano??

Postby zpj61 » 13 September 2019, 6:35

Ci ho sbattuto il naso qualche volta pure io ma non ho trovato un modo e il tempo per isolare il problema e mandare il classico progettino di esempio. Ogni tanto succede e faccio quello che fai tu, isolo le variabili da passare alla funzione e poi ne riprendo il valore. Avevo notato che anche nei cicli for e while succedeva però poi lo hanno sistemato. Lasciamo perdere le considerazioni sul tempo perso a sistemare il codice...
User avatar
zpj61
 
Posts: 530
Joined: 20 November 2015, 8:20

Re: parametri output... ma funzionano??

Postby d.termini » 13 September 2019, 6:48

Anche noi seguiamo lo stesso discorso di zpj61.
Aggiungo anche: attento con le variabili di tipo oggetto, non puoi passarle come inout e devi passare l'istanza e usare quella, se fai un new() dentro alla funzione quell'istanza resta interna alla funzione.
Code: Select all
//Data la funzione
funzione(object o)
{
o.valore = "pippo"
}

//Questo funziona
MiaClasse obj = new()
funzione(obj)
DTTLogMessage(obj.variable)

mentre
Code: Select all
//Data la funzione
funzione(object o)
{
o = new()
o.valore = "pippo"
}

//Questo NON funziona
MiaClasse obj = null
funzione(obj)
DTTLogMessage(obj.variable) <- errore, "obj" è null

Sarebbe stato comodo per restituire 2 o più istanze di oggetti diversi, ma per fare questo conviene passare un IDMap (sempre istanziandola nella routine chiamante come nel primo caso)
d.termini
 
Posts: 480
Joined: 13 November 2017, 8:41

Re: parametri output... ma funzionano??

Postby g.lanzi » 13 September 2019, 9:12

Rispondo volentieri alla richiesta di chiarimenti e di riferimenti di documentazione.

I parametri delle funzioni di Instant Developer non sono mai passati per riferimento (stile byRef, per intenderci), ma sempre per valore. Passando una variabile di tipo Object non si passa un puntatore come si potrebbe fare in C++. Quindi scrivere parametro := new() non ha effetti all'esterno.

Come sapete all'interno di Instant Developer Foundation i tipi primitivi sono istanze della classe IDVariant. La classe contenente il valore primitivo (diciamo una stringa) è sempre passata e il framework non fa altro che chiamare la funzione interna che ne imposta il valore.
Questo non può funzionare se:
1) si passa un oggetto (cosa che non dovrebbe essere nemmeno permessa, in effetti).
2) si fa parametro := new() nel codice della funzione chiamata.
3) si passa una proprietà di una classe

Nella pagina di documentazione dei Parametri è indicato che per utilizzare il Modificatore Output i parametri passati devono essere costituiti da variabili scalari.
https://doc.instantdeveloper.com/?ARTID=vce_defpar&LANG=it

L'unica strada percorribile è passare una semplice variabile.

In versione 10.1 è stato permesso di passare comunque espressioni o costanti, perché poteva essere utile agli scopi della procedura chiamata. Ma all'esterno il valore non viene passato.
https://doc.instantdeveloper.com/?ARTID=7098ED1D-A0C7-4578-A953-F4BE510ABC81&LANG=it .


Ho notato inoltre che dal VCE non è possibile impostare in/out in un parametro di tipo oggetto, ma ho visto che è possibile aprire le proprietà del parametro e modificarlo. Oppure creare un parametro di output string e poi cambiare tipo in un IDDocument.
Anche se con questi due metodi è possibile impostare il parametro come di output, poi si riceve un errore di compilazione (so che questo non è esattamente il caso proposto, ma per completezza l'ho indicato).
https://www.screencast.com/t/LhOMhIjn22od
Giuseppe Lanzi
Director of Support services
Pro Gamma S.p.A.
User avatar
g.lanzi
Pro Gamma
Pro Gamma
 
Posts: 3239
Joined: 29 September 2010, 10:24
Location: Bologna

Re: parametri output... ma funzionano??

Postby Gattonero » 13 September 2019, 13:20

g.lanzi wrote:I parametri delle funzioni di Instant Developer non sono mai passati per riferimento (stile byRef, per intenderci), ma sempre per valore. Passando una variabile di tipo Object non si passa un puntatore come si potrebbe fare in C++. Quindi scrivere parametro := new() non ha effetti all'esterno.


Strano perchè ho notato, anzi usato più di qualche volta questo codice (esempio semplificato)
medotoAdd.jpg
medotoAdd.jpg (16.05 KiB) Viewed 65 times


chiamato da
Metodo Esempio.jpg
Metodo Esempio.jpg (39.82 KiB) Viewed 65 times


SE fosse passato per valore mi aspetterei che le modifiche valgano solamente all'interno della chiamata, ma invece
Risultato.jpg
Risultato.jpg (22.13 KiB) Viewed 65 times


All'esterno della routine risultano esserci 2 elementi, quindi la collection viene passata ByRef (o per lo meno mi pare cosi)

Allego anche il progettino d'esempio da cui ho ricavato le immagini
Nuovo Progetto.zip
(440.67 KiB) Downloaded 1 time


Ho forse capito io male qualcosa?
User avatar
Gattonero
 
Posts: 504
Joined: 28 August 2012, 16:49

Re: parametri output... ma funzionano??

Postby d.termini » 13 September 2019, 13:34

In questo caso stai passando la collection, non "nuova classe", la funzione Aggiungi manipola la collection che avevi già fuori, quindi è corretto. Passare un oggetto ByVal passa l'oggetto.

Il ByRef serve quando vuoi passare la variabile dell'oggetto a null (sostanzialmente il riferimento ad un'area di memoria, vuota), istanziarla dentro alla funzione (perché magari c'è tutta una procedura per farlo) ed usarla nel chiamante (il mio secondo esempio). Ed è questo che InDe non fa.
d.termini
 
Posts: 480
Joined: 13 November 2017, 8:41

Re: parametri output... ma funzionano??

Postby g.lanzi » 13 September 2019, 13:42

Esatto @d.termini. Questo perché tutti i linguaggi implementano il byRef (o scritture analoghe), ad esempio Java e Javascript hanno questa feature.
Giuseppe Lanzi
Director of Support services
Pro Gamma S.p.A.
User avatar
g.lanzi
Pro Gamma
Pro Gamma
 
Posts: 3239
Joined: 29 September 2010, 10:24
Location: Bologna

Re: parametri output... ma funzionano??

Postby Gattonero » 13 September 2019, 13:45

mmm... allora c'è una terminologia di fondo che mi è oscura .. ero abituato che passare un oggetto ByVal non lo altera (o per lo meno le modifiche vanno perse) al momento dell'uscita dalla routine chiamante, mentre il ByRef passando il puntatore all'oggetto (classe o collection che sia) permette di rendere "stabili" (mi si passi il termine) anche al di fuori della routine chiamata.
Per me, fare un New oppure chiamare un metodo alla fin fine li vedo uguali (quindi che il new non funzioni e l'add si.. questo mi perplime ecco) sarà che sono troppi anni che non uso più VB (dalla 6.0)...

https://www.homeandlearn.co.uk/NET/nets9p4.html

un po' come qui
User avatar
Gattonero
 
Posts: 504
Joined: 28 August 2012, 16:49

Re: parametri output... ma funzionano??

Postby Gattonero » 13 September 2019, 13:56

ho verificato bene la cosa... tutto dipende da UN SOLO FATTORE.. da dove l'oggetto è instanziato..

1.jpg
1.jpg (22.16 KiB) Viewed 53 times

NON funziona da errore

2.jpg
2.jpg (25.26 KiB) Viewed 53 times

FUNZIONA e restituisce 1 (non 0)

3.jpg
3.jpg (23.4 KiB) Viewed 53 times

(corpo della funzione)

Come se nel caso del null fosse un ByVal e in caso <>null ByRef
User avatar
Gattonero
 
Posts: 504
Joined: 28 August 2012, 16:49

Re: parametri output... ma funzionano??

Postby theguru » Yesterday, 17:29

@gattonero
a dirla tutta a me il discorso delle collection, come dai tuoi esempi, mi torna.
Passare un oggetto vuol dire per forza di cose passare un puntatore all'istanza. Se l'oggetto (doc o collection o altro) è null non vi è ancora puntatore, e la funzione "chiamata" non riesce ad agganciare l'oggetto definito nella funzione chiamante. Questa cosa la potresti fare in C++, che mette a disposizione l'aritmetica dei puntatori e la gestione diretta della memoria, ma ci sta che INDE non lo preveda.

@g.lanzi
1) quello che mi torna meno è perché, il passaggio per riferimento (by ref), non sia stato implementato: se in particolare voi già fate il boxing della variabile dentro l'istanza di una classe, non sarebbe sufficiente passare il puntatore a quella classe? in questa situazione mi sembra addirittura più complesso passare variabili per valore, piuttosto che per riferimento

2) quello che mi destabilizza nella vostra implementazione, è che il valore viene ritornato modificato non in base al fatto che la variabile sia scalare, ma in base a come questa var sia inizializzata: ad esempio se inizializzata all'interno di un ciclo for_each dei record di una tabella, il valore NON viene ritornato. Se invece è dichiarata da codice come nel mio esempio (post n.1) allora torna il valore corretto. Ma entrambe sono variabili scalari.

3) questa è la parte importante: do per scontato che, indipendentemente da chi abbia concettualmente ragione, voi NON modificherete nulla alla attuale implementazione, non fosse altro che per le conseguenze che potrebbe avere sul codice già scritto dai vostri utenti.
Ma resta il fatto che, se mi trovo nella situazione di dover dare in pasto ad una funzione una decina di parametri (situazione non così assurda) è pazzesco pensare che debba scrivere 21 righe di codice al posto di una sola (10 righe per inizializzare 10 var, assegnando il valore, altre 10 per riassegnare il valore di ritorno). Non solo per il tempo necessario alla scrittura, ma anche per la leggibilità e manutenzione del codice.
Quindi ti chiedo, all'interno di INDE, non potendo passare le var per riferimento, quale strategia suggerisci di usare in casi come quello sopra? ritornare un idmap? istanziare una classe con una serie di proprietà e passare quella (articolato e laborioso)? mettere tutto in un array di parametri? (...)

Grazie come sempre per la tua partecipazione
User avatar
theguru
 
Posts: 645
Joined: 29 January 2014, 13:01


Return to Tips & Tricks - Foundation

Who is online

Users browsing this forum: No registered users and 22 guests

cron