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