Page 1 of 1
Erro un poco extraño TDataBase
Posted: Sun Mar 20, 2016 4:14 pm
by RenOmaS
Buenas,
A alguien le sucede esto:
#include "FiveWin.ch"
function Main()
? TDataBase():cdriver //Resultado: 'DBFNTX'
REQUEST DBFCDX
rddsetdefault( "DBFCDX" )
? RddSetDefault(), TDataBase():cdriver // Resultado: "DBFCDX", 'DBFNTX', este ultimo debería ser 'DBFCDX'
return nil
Ahora si hacemos esto
#include "FiveWin.ch"
function Main()
REQUEST DBFCDX
rddsetdefault( "DBFCDX" )
? RddSetDefault(), TDataBase():cdriver // Resultado: "DBFCDX", 'DBFCDX', resultado correcto.
return nil
Re: Erro un poco extraño TDataBase
Posted: Sun Mar 20, 2016 5:43 pm
by Antonio Linares
Americo,
A mi me parece correcto lo que sucede:
Hasta que no se define el RDD por defecto usando RddSetDefault(), se usa el DBFNTX
Code: Select all
? TDataBase():cdriver //Resultado: 'DBFNTX
REQUEST DBFCDX
rddsetdefault( "DBFCDX" )
Re: Erro un poco extraño TDataBase
Posted: Sun Mar 20, 2016 8:42 pm
by RenOmaS
Antonio
Si solo hacemos esto el resultado es correcto
Code: Select all
REQUEST DBFCDX
rddsetdefault( "DBFCDX" )
//y hacemos
tdatabase():cDriver // resultado 'DBFCDX -> resultado correcto
Pero, si hacemos esto
Code: Select all
//hacemos esto primero
? tdatabase():cDriver //Resultado 'DBFNTX'
//definimos el RDD
REQUEST DBFCDX
rddsetdefault( "DBFCDX" )
//y hacemos nuevamente
? tdatabase():cDriver // resultado 'DBFNTX' , cuando deberia ser DBFCDX
Cuando hacemos 'tdatabase():cdriver' por segunda vez no trae el RDD por defecto.
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 1:11 am
by xmanuel
Parece que trate esa data como una classdata y solamente se inicializara con la primera llamada a la funcion de clase.
Para evitar eso tal vez se debería cambiar la definicion de la data:
Code: Select all
DATA cDriver AS CHARACTER INIT RddSetDefault()
por:
Code: Select all
// En la definicion:
DATA FcDriver PROTECTED
METHOD cDriver SETGET
// y en implementacion algo así:
METHOD cDriver( cRDD ) CLASS TDataBase
if ValType( cRDD ) == "C"
::FcDriver := Upper( cRDD )
else
if ValType( ::FcDriver ) != "C"
::FcDriver := RddSetDefault()
endif
endif
return( ::FcDriver )
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 8:22 am
by Antonio Linares
Américo,
Pruéba asi:
? tdatabase():New( ,, "DBFNTX" ):cDriver
REQUEST DBFCDX
rddsetdefault( "DBFCDX" )
? tdatabase():New( ,, "DBFCDX" ):cDriver
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 10:43 am
by RenOmaS
Manuel:
Si, lo extraño es que en la clase no esta definido como classdata.
Tu solución que se podría implementa en la TDataBase.
Antonio:
De esa forma, funciona para o ejemplo postado.
Hemos hecho ese pequeño ejemplo, para mostrar ese comportamento "extraño".
Para superar esto en nuestras aplicaciones hemos tenido que cambiar la lógica.
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 10:51 am
by Antonio Linares
El problema viene de esta línea:
DATA cDriver AS CHARACTER INIT RddSetDefault()
Por lo que se ve, esa cláusula INIT no se actualiza
Podria considerarse un bug de Harbour creo
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 10:57 am
by RenOmaS
Antonio,
Debe ser un comportamiento erroneo del motor de objects de harbour?, por ejemplo
Code: Select all
#include "FiveWin.ch"
Static nContador
Function Main()
nContador := 1
? TClase():nContador //resultado 2
? TClase():nContador // Resultado 2
? TClase():nContador // Resultado 2
? TClase():nContador // Resultado 2
Return Nil
CLASS TClase
DATA nContador INIT ++nContador
ENDCLASS
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 11:00 am
by Antonio Linares
Si, a eso me refería
Parece un bug de Harbour
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 11:03 am
by Antonio Linares
Lo acabo de reportar en la lista de desarrollo de Harbour:
https://groups.google.com/forum/#!topic ... wirwvF5KOE
Re: Erro un poco extraño TDataBase
Posted: Mon Mar 21, 2016 11:04 am
by RenOmaS
Gracias
Re: Erro un poco extraño TDataBase
Posted: Wed Mar 23, 2016 7:34 am
by nageswaragunupudi
The behavior is the same with both Harbour and xHarbour. So, instead of considering it as a bug, we better consider it as the expected behavior.
The value is assigned to the data at the time creation of the object, not at the time of every instantiation. Following example clarifies the behavior.
Code: Select all
#include "fivewin.ch"
function Main()
? time(), test():ctime
? time(), test():ctime
? time(), test():new():ctime,test2():new():ctime,test3():new():ctime
return nil
class test
data ctime init time()
endclass
class test2 from test
endclass
class test3 from test
data ctime init time()
endclass
I confess that I did not know this earlier.
The lesson is that we should not use INIT to assign the result of a function, whose value may change during runtime.
We need to modify tdatabase class. These are the two changes made:
Old code:
Code: Select all
DATA cDriver AS CHARACTER INIT RddSetDefault()
New code:
Code: Select all
DATA cDriver // AS CHARACTER INIT RddSetDefault() // FWH16.03
Old code:
Code: Select all
METHOD Use() CLASS TDataBase
if Empty( ::cAlias )
::cAlias := cGetNewAlias( 'TDF' )
endif
if Select( ::cAlias ) > 0
::cAlias := cGetNewAlias( Left( ::cAlias, 3 ) )
endif
dbUseArea( .t., ::cDriver, ::cFile, ::cAlias, ::lShared, ::lReadOnly )
if Alias() == ::cAlias
::SetArea( Select() )
endif
return ::Used()
New code:
Code: Select all
METHOD Use() CLASS TDataBase
if Empty( ::cAlias )
::cAlias := cGetNewAlias( 'TDF' )
endif
if Select( ::cAlias ) > 0
::cAlias := cGetNewAlias( Left( ::cAlias, 3 ) )
endif
DEFAULT ::cDriver := RDDSETDEFAULT() // Now inserted FWH 16.03
dbUseArea( .t., ::cDriver, ::cFile, ::cAlias, ::lShared, ::lReadOnly )
if Alias() == ::cAlias
::SetArea( Select() )
endif
return ::Used()
Re: Erro un poco extraño TDataBase
Posted: Wed Mar 23, 2016 10:36 am
by Carles
Hi,
I think the best option is when you definied the object, the same concept as now but initialized data ::cDriver correctly
Code: Select all
METHOD New( ncArea, cFile, cDriver, lShared, lReadOnly ) CLASS TDataBase
if PCount() > 1
if ValType( ncArea ) == 'C'
::cAlias = ncArea
endif
if ValType( cFile ) == 'C'
::cFile = cFile
endif
if ValType( cDriver ) == 'C'
::cDriver = Upper( cDriver )
else
::cDriver = RDDSETDEFAULT()
endif
...
Once the object is created, you should'nt change RDD
Re: Erro un poco extraño TDataBase
Posted: Fri Mar 25, 2016 6:55 pm
by RenOmaS
Nages and Charles
Thanks