Newsgroup: it.comp.lang.visual-basic
Titolo: vb6: tipi pubblici, questo errore mi perseguita

Programmatori della domenica (cioe' oggi), datemi una mano, che sono
bloccato.
Questo errore mi perseguita da tempo:
Only public user defined types defined in public object modules can be used
as parameters or return types for public procedures of class modules or as
fields of public user defined types
Definisco un tipo in un modulo, un .bas per intenderci. Uso o meno la
keyword public, visto che dovrebbe essere pubblico per default
Poi lo uso come valore di ritorno di una funzione pubblica di una classe, e
vb mi spernacchia in quella maniera.
Dove sto sbagliando?
Non e' che dopo tanti hanni non ho capito cos'e' un object module?
nel .bas:
Public Type pino
    a as long
end type
nel .cls
public function abc() as pino
...
end function
Enrico

end function
Questa è una cosa su cui mi sto scontrando spesso ultimamente e la trovo
molto scomoda, ma almeno nel tuo caso è anche corretto.
Spiego: un modulo di classe è in realtà un oggetto a se stante, quindi non
può andare ad elemosinare tipi, variabili e quant'altro al di fuori del suo
"mondo".
Questo è un po' la filosofia della programmazione ad oggetti che per essere
modulare deve poter contere su oggetti (appunto) indipendenti tra loro.
Cio' non toglie che l'incapacità di VB di restituire tipi da funzioni di
classe è altamente frustrante (ma davvero non si può fare? neanche
barando?).



...


fatta a mano.
Sì, sì, infatti, come ho detto, è alquanto scomodo e, secondo me, frutto di
una programmazione superficiale del runtime di VB, il fatto che una
funzione/proprietà non possa restituire tipi definiti dall'utente.
Quello che io ritenevo corretto è il fatto che da una tua classe non si
possa andare a pescare tipi o membri pubblici definiti in altre classi o
moduli.
Ciao.
Mi spiace non esserti stato d'aiuto, ma piacerebbe anche a me avere la
soluzione!

fields of public user defined types
--
Roal Zanazzi
z...@iol.it

defined......

come la documentazione di VB4 e VB5 ti spiega, non e' possibile usare un UDT
(user defined type) come membro pubblico di una classe. Questo perche' COM
(ossia OLE) non supporta gli UDT. Praticamente: non puoi usare un UDT come
proprieta' Public (ossia una proprieta' dichiarata nella sezione
Declarations, ne' come valore di ritorno di una Function Public.
Questo non e' piu' vero in VB6.
Se vuoi aggirare il problema in VB4/5 e' sufficiente che sostituisci il tuo
Type con una Class di identica definizione.

VB6 a differenza di VB5 permette l'uso di properties che restituiscono
strutture.
Dove è l'inganno?, sta nel fatto che le classi devono stare in una ActiveX
DLL e non in una classe private allo standard exe.
esempio: nell ActiveX DLL (class1.cls)
Option Explicit
Public Type pino
    a As Long
    b As Long
End Type
Public Property Get Prova() As pino
End Property
in un client (Standard EXE)
Dim obj As Project1.Class1
Set obj = New Project1.Class1
Print obj.Prova.a
...A questo aggiungici anche il fatto che se gli oggetti sono distribuiti su
macchine remote devi installare DCOM98.
Ciao,
Corrado

barando?).
Ehm... ok partiamo dalla traduzione:
Solo gli UDT (abbreviazione di User Defined Type: in pratica le strutture
Type-End Type) pubblici definiti in moduli oggetto pubblici (file .BAS)
possono essere utilizzati come parametri o possono essere ottenuti come dati
da procedure pubbliche nei moduli di classe (file .CLS) o come campi di UDT
pubblici.
NB: questa è una novità di VB6. Con VB5 NON si possono utilizzare UDT come
parametri o come tipi di dati restituiti da funzioni pubbliche delle classi.
Neanche barando !
Sto preparando un messaggio con descritte tutte le novità del VB6 (no
tranquilli.. non metterò anche i BUG, altrimenti mi sa che viene un
messaggio da 200 Kb), così finalmente taglieremo la testa al toro,
considerando che la documentazione allegata al Working Model del VB6 è
veramente scarna.
Zeross

...


...


Se per COM intendi oggetti COM (ActiveX DLL e ActiveX EXE) sí.
Non ho mai avuto problemi, basta che stai attento alla corretta
registrazione e deregistrazione degli stessi, man mano sviluppi l'oggetto.
Non tutte le interfacce sono disponibili,peró per il momento non ne ho avuto
l'esigenza.
Ovviamente per applicazioni "molto" particolari il C++ é meglio ,peró é
molto piú complesso.
Ciao
Corrado

4 Non usate tipi di dati di prima classe, usate sempre Variant.
    AAAAAARRRRRGGGGGHHHH!!!!!
    qui dev'esserci statu un disturbo sulla linea mentre ricevevo il
messaggio: pensa che mi č arrivato scritto di utilizzare i variant... :)
Ciao.


So che mi potresti rispondere "comprati il libro e leggitelo", ma sarei
proprio interessato ad una breve spiegazione per i punti 3 e 4.
--
Roal Zanazzi
z...@iol.it

4 Non usate tipi di dati di prima classe, usate sempre Variant.
ARGHHHHH !!!!!   ECCO LA BESTIALITAAAAAAA' !!!!!!
PER QUANTO POSSIBILE NON (e lo ripeto: NON) USATE MAI I VARIANT
!!!!!!!!!!!!!
SONO IN ASSOLUTO LE VARIABILI PIU' LENTE !!!!!!!
Cercate di usare invece un tipo di dato preciso, il vostro programma ne
guadagnerà in velocità.
Mi spiace, ma non sono d'accordo con Burn, io seguo i dettami di Bruce
McKinney ("Hardcore Visual Basic" MS Press, Mondadori Informatica) e Dan
Appleman ("Visual Basic 5.0 Win32 API" MS Press, Mondadori Informatica) ed
evito i VARIANT come la PESTE.
In questo modo si occupa meno memoria (I Variant sono un tipo di dati a 16
bit) e si evita un mucchio di coercion implicite che rallentano le
operazioni sui dati.
Meditate gente... meditate.... anzi, per emulare una celebre pubblicità:
PROVARE, PER CREDERE !!!
Zeross

sottoscrivo quanto detto da Zeross
lavoro in VB da 3 anni a tempo pieno
inoltre usare variabile "tipate" anziche' generiche (ossia Variant) permette
di intercettare errori al momento della compilazione, errori che altrimenti
verrebbero fuori solo in esecuzione


spiegazione punto 3:
Quando si afferma "Non passate parametri di funzione per riferimento"
si intende quando il linguaggio lo permette. Se si prova a passare una
struttura byval viene generato un errore in compilazione!!
NB se si passa un oggetto byval non c'e' errore ma è implicito che gli
oggetti sono sempre passati per riferimento!
spegazione punto 4: ho mandato un'altra risposta !! (a pollo)


Come vedo il tipo Variant non riscuote molte simpatie.
Mi dispiace! ( :-( )
Soprattutto mi dispiace che luminari dell'informatica quali Dan
Appleman (anche nell'importantissimo libro Sviluppo di Componenti ActivX
con Visual Basic 5.0 dedica qualche pagina all'argomento) la pensino circa
come Voi.
Ora però mi sento in dovere di controbattere e
provo in sintesi a descrivere qualche argomentazione a favore dei Variant
Il primo fatto da tenere ben presente è che non è vero che
l'uso di variabili di tipo dati di prima classe pemette di intercettare
errori
al momento della compilazione! Ciò è vero in C era vero in VB3 ma
dall'avvento
del VB4 al momento della compilazione non viene più effettuato un controllo
stretto dei tipo ma viene attivata la cosidetta "conversione implicita
dei tipi", che dal mio punto di vista ci obbliga a ragionere sempre come
se tutte le variabili fossero variant. Riporto un esempio:
dim i as integer
dim s as string
s = "CIAO"
i = s
il vb3 in compilazione dava errore. Il vb4 e 5 e 6 NO!! Solo quando il
nostro
programma (magari già consegnato da 6 mesi) prova ad eseguire queste
operazioni
si blocca con error Run-Time 13.
Anche a me questo comportamento non piace e preferirei un controllo stretto
dei tipi, ma purtroppo (o per fortuna) il fatto è che oggi VB funziona così
e non credo che microsoft sia disposta a tornare sui suoi passi.
Venedo quindi a mancare il vantaggio principale che si avrebbe con l'uso
delle
variabili di prima classe non vedo perchè non avvantaggiarsi di tutte le
potenzialità che i Variant posseggono fra cui i valori empty e null...
I vantaggi dell'uso variant vengono poi amplificati se associati alla
tecnica
di controllo preventivo da me assai preferita alla gestione dell'errore.
Esaminate per esempio le tre funzioni seguenti:
'-------------------------------
CalcoloIva_A(byval vData)
  if IsNumeric(vData) then
    CalcoloIva_A = vData * mvarPercentualeIva
  else
    CalcoloIva_A = null
    RaiseEvent "Evento di errore"
  endif
End Sub
'-------------------------------
CalcoloIva_B(byval vData) as double
  on error goto ErrorHandler
  CalcoloIva_B = vData * mvarPercentualeIva
  exit sub
ErrorHandler:
  CalcoloIva_B = 0
  RaiseEvent "Evento di errore"
End Sub
'-------------------------------
CalcoloIva_C(byval vData as double) as double
  CalcoloIva_C = vData * mvarPercentualeIva
End Sub
Per me non c'e' alcun dubbio che la funzione A è meglio.
La C che per i puristi è più elegante non risolve il problema del controllo
ma lo sposta solo ad livello superiore! Se vData fosse il contenuto di una
TextBox non potrei usarla direttamente immaginate:
CalcoloIva_C(Text1.Text as double) as double
  CalcoloIva_C = vData * mvarPercentualeIva
End Sub
La B mi obbliga ad attivare l'intercettazione degli errori anche per errori
prevedibili. Anche questo è un altro punto sul quale i pareri credo si
differenziano
ma, per quel che mi riguarda, preferisco sempre gestire tutti gli errori
prevedibili con un controllo preventivo e sviluppare con l'intercettazione
settata su "arresta ad ogni errore". Inserisco quindi l'ErrorHandler solo
ed esclusivamente per intercettare gli errori imprevisti (tenendone magari
un log!!).
Per implementare questo stile di programmazione l'uso dei variant è
indispensabile.
PS:
Pensate al problema dell'euro! Quanti programmatori staranno modificando SW
trasformando variabili long in variabili double. Se si fosse potuto
utilizzare
da sempre il variant tale problema avrebbe di certo un impatto minore.
Rimane il problema delle prestazioni.
Ok. sicuramente i variant sono lenti Jon Burn (fans dei variant) riporta nel
suo libro alcuni test dai quali si evince che i variant sono lenti circa il
doppio
rispetto ad un integer. In realtà Burn bara in quanto tali test sono
effettuati
usando la modalità di progettazione e quindi non compilando in modo
ottimizzato
il codice. Se si fanno particolari test con i programmi compilati si nota
che
i variant possono essere anche 40 volte più lenti degli integer.( :-O )
A me pero' questo non spaventa in quanto credo che in una generica
applicazione
(almeno in quelle con cui io ho normalmente a che fare) raramente il
sovraccarico
dato dall'uso dei variant rispetto agli integer sia rilavente rispetto ai
tempi per
l'acceso ai dati o per il caricamento dei form!. E' evidente che anch'io
se debbo effettuare un calcolo iterativo o implementare un ciclo oneroso uso
tipi
di basso livello ma la logica in cui mi muovo è:
" Usare normalmente Variant ed eccezionalmente tipi di dati primitivi solo
quando
serve per motivi di prestazioni."
Con questa ho esaurito il tempo dedicato alle news per tutto il 1999!!
      Salve e buon Lavoro a tutti


Io, invece, seguo questa regola:
"Usare sempre i tipi di dati piu' logicamente consoni al problema; usare i
variant solo quando servono veramente e dopo essersi chiesto per almeno 3
volte se proprio non e' possibile farne a meno".
--
Roal Zanazzi
z...@iol.it

oggetti sono sempre passati per riferimento!
E' solo un'ipotesi, ma siamo sicuri che quando passi un oggetto ByVal VB non
crei una copia temporanea dell'oggetto e usi un riferimento a quello, invece
di usare il riferimento all'oggetto passato? In questo caso passare ByVal
penalizzerebbe le prestazioni (c'e' anche il tempo di copia dell'oggetto)...
--
Roal Zanazzi
z...@iol.it

i = s
...e devo dire che, anche lanciando il programma interpretato da
ambiente di sviluppo, VB5 mi da' un bell'errore di run-time 13...
Non e' che quello che ha detto Corrado e' valido solo per il VB6?
Marco Gentili
EmmeCiQuadro S.n.c.
m.ge...@emmeciquadro.it


Appunto, LANCIANDOLO (e SOLO se esegui il codice della funzione
incriminata).
Il punto e' che il controllo sui tipi (in teoria) dovrebbe essere fatto
DURANTE la compilazione, ossia, premi F5 (o crei EXE) e ti "dovrebbe"
segnalare l'errore...
Altrimenti che senso avrebbe dichiarare i tipi... e avrebbe ragione (ma solo
per questo ;-) Corrado, quando dice che e' lo stesso usare i Variant!!!
Non ho provato a compilare l'EXE...
Comunque gia' il fatto che lanciando il programma da VB non ci sia il
controllo sui tipi mi lascia sconcertato!!!
Mi viene il dubbio che l'abbiano (leggi Microsoft) fatto apposta per poter
dire "guardate com'e' veloce il compilatore di VB"... porcazozz!
--
Roal Zanazzi
z...@iol.it

incriminata).
Ah, sorry!
Non avevo capito qual'era il reale punto del discorso... :-)
In effetti, avete perfettamente ragione. La compilazione se ne
strafrega allegramente del controllo dei tipi! >B-(
Pessimismo... e fastidio...
