Page 1 of 1

Usar o no variables publicas.

Posted: Tue Apr 28, 2020 1:21 pm
by jvtecheto
Hola el tema es este

Variables publicas si o no. ?
yo siempre he leido que no es aconsejable utilizarlas, por eso ahora utilizo el siguiente sistema.
como siempre tenemos que acceder a variables que estan en otros modulos. Yo declaro las variables static.
y las paso a otros modulos asi.

Code: Select all

FUNCTION GetWndMain()
RETURN oWndMain  
 
y en el modulo que la tengo que utilizar.

Code: Select all

oWndMain := GetWndMain()
 
El tema funciona bien, pero en cada modulo que voy a utilizarla, que sera en casi todos tengo que llamar a la funcion.
Si utilizara variable publica me ahorraria esto, seria mejor?

¿Como lo haceis vosotros para acceder a una variable de otro modulo?

Espero haberme explicado bien, muchas gracias por vuestra ayuda.

Saludos.

Jose.

Re: Usar o no variables publicas.

Posted: Tue Apr 28, 2020 2:00 pm
by karinha
Puedes usarlo sin ningún problema. cuando salga del programa use CLEAR MEMORY.

Re: Usar o no variables publicas.

Posted: Tue Apr 28, 2020 2:03 pm
by cnavarro
Como dice el compañero, se pueden seguir utilizando, pero a mí particularmente no me gusta su uso, prefiero sólo utilizar las variables definidas en su propio módulo, por lo que en todo caso utilizo la técnica que has descrito ( llamar a la function que me devuelva la variable que utilizo )

Re: Usar o no variables publicas.

Posted: Tue Apr 28, 2020 2:56 pm
by Antonio Mart.
Yo tampoco utilizo ni Public ni Private, pero si tengo una Public oApp

Re: Usar o no variables publicas.

Posted: Tue Apr 28, 2020 3:11 pm
by cnavarro
Antonio Mart. wrote:Yo tampoco utilizo ni Public ni Private, pero si tengo una Public oApp
Sí, también es una práctica muy habitual, en la que existe una clase TApp o algo asi
En ese caso, lo lógico es convertir a DATAs cada una de esas variables públicas y obtenerlas a partir del objeto oApp, o, yo incluso veo mejor hacer en una DATA un hash que contenga las el valor de las antiguas variables públicas y, en el caso de ser static la variable oApp, y no public devolver el hash del key que envías como parámetro.
Utilizando este método, sólo necesitas una llamada a una sola function

Code: Select all

Function GetVarPublic( cVar )
// Comprobar que lo que recibe como parámetro está definido como key en el hash ( hb_HHashkey() )
Return oApp:aPublics[ cVar ]
 

Re: Usar o no variables publicas.

Posted: Tue Apr 28, 2020 9:48 pm
by xmanuel
Creo que deberías usar lo que más te guste o más práctico sea para ti.

En nuestro querido y viejo clipper había unos límites fáciles de alcanzar de variables públics y privates en la TABLA DE SÍMBOLOS, pero esa limitación ya no existe en Harbour.
Personalmente por inercia tampoco las utilizo, pero me reitero sólo por inercia.

Yo como soy muy de POO uso una clase TCore o TKernel compuesta solo de datas que serían las variables que voy a usar en mis prg
Es más se me ocurre que si esas datas son CLASDATA no habría ni que instaciar un objeto de esa clase y se podría hacer algo así:

Code: Select all

CLASS TKernel
    CLASSDATA xVar1
    CLASSDATA xVar2
    CLASSDATA xVar3
ENDCLASS
// Y en el programa se podría hacer
TKernel:xVar1 := "Esto es una prueba"
? TKernel:xVar1
 
Es mas podría haber una sola CLASSDATA de tipo Hash que aumentaria segú se requiera:

Code: Select all

CLASS TKernel
    CLASSDATA hVar 
ENDCLASS

TKernel:hVar[ "DNI" ] := "89436870T"
? TKernel:hVar[ "DNI" ]

 
Bueno lo dejo porque se me está disparando la perola!!!
:D

Re: Usar o no variables publicas.

Posted: Tue Apr 28, 2020 9:52 pm
by carlos vargas
Últimamente me hecho adicto a los hash
en mis app tengo un

Code: Select all

en el modulo inicial
PUBLIC hGlobal := {=>}
hGlobal[ "userid" ] :=
hGlobal[ "userlevel" ] :=
hGlobal[ "usermodules" ] := 
 
y asi, las que necesite.

Re: Usar o no variables publicas.

Posted: Tue Apr 28, 2020 10:54 pm
by horacio
Hay una clase que yo utilizo que se llama TPublic, donde defines solo una variable pública y declaras las que quieras dentro de ella.

Code: Select all

Public o

With Object o := TPublic() : New()
    :Add( "usuario" )
    :Add( "passw" )
EndWith

 
Tiene varios métodos para gestionarla.
Saludos

Re: Usar o no variables publicas.

Posted: Wed Apr 29, 2020 1:16 am
by Antonio Linares
Horacio,

Puedes publicar aqui el código fuente de la clase TPublic que comentas ? gracias

Re: Usar o no variables publicas.

Posted: Wed Apr 29, 2020 2:06 am
by horacio
La clase es de Daniel Andrade, un coterraneo :D

Code: Select all

 *  -----------------------------------------------------------------------------
 *  TPublic()
 *  Clase para el reemplazo de Variables Publicas
 *  Version 2.2b - 01/04/2003
 *
 *  Andrade A. Daniel
 *  Rosario - Santa Fe - Argentina
 *
 *  andrade_2knews@hotmail.com
 *  http://www.dbwide.com.ar
 *
 *  Aportes: [ER]   Eduardo Rizzolo
 *           [WA]   Wilson Alves - wolverine@sercomtel.com.br 18/05/2002
 *           [JJMG] Juan J. Mendez Gonzalez
 *
 *  DATAS
 *  -----------------------------------------------------------------------------
 * aVars      - Arreglo de variables
 * cName      - Nombre ultima variable accedida
 * nPos       - Valor ultimo variable accedida
 * lAutomatic - Asignación automatica, por defecto TRUE [WA]
 *
 *  METODOS
 *  -----------------------------------------------------------------------------
 * New()      - Contructor
 * Add()      - Agrega/define nueva variable
 * Del()      - Borra variable
 * Get()      - Accede a una veriable directamente
 * Set()      - Define nuevo valor directamente
 * GetPos()   - Obtener la posición en el array
 * Release()  - Borra todas las variables
 * IsDef()    - Chequea si una variable fue definida
 * Clone()    - Clona la DATA aVars
 * nCount()   - Devuelve cantidad de variables definidas
 * Save()     - Salva DATA aVars
 * Restore()  - Restaura DATA aVars
 *
 *  NOTA
 *  -----------------------------------------------------------------------------
 * Para acceder al valor de una variable, se puede hacer de 2 formas,
 * una directa usando oPub:Get("Codigo") o por Prueba/Error oPub:Codigo,
 * este último es mas simple de usar pero más lento.
 *
 * Para definir un nuevo valor a una variable tambien puede ser por 2 formas,
 * directamente por oPub:Set("Codigo", "ABC" ), o por Prueba/Error
 * oPub:Codigo := "ABC".
 *
 * Atencion: Los metodos Get() y Set() no controlan si la variable existe,
 * para ganar en velocidad.
 *
 * Las variables definidas NO son case sensitive.
 *
 *  MODIFICACIONES Y AGREGADOS
 *  -----------------------------------------------------------------------------
 * 2.2b Correción Bug en metodo Add() sobre FWH.
 * 2.2a Modificado para não restringir o número de variáveis em [x]Harbour [WA]
 * 2.2  Modificada para funcionar en [x]Harbour
 *
 * 2.1  Se guarda el Nombre y Posición de la última variable accedida para incrementar
 *      la velocidad. (Implementado por Eduardo Rizzolo)
 *
 *  EJEMPLO
 *  -----------------------------------------------------------------------------
 * FUNCTION Test()
 * local oP := TPublic():New(), aSave, nPos
 *
 * oP:Add("Codigo")           // Defino variable sin valor inicial
 * oP:Add("Precio", 1.15)     // Defino variable con valor inicial
 * oP:Add("Cantidad", 10 )
 * oP:Add("TOTAL" )
 *
 * // Acceso a variables por prueba/error
 * oP:Total := oP:Precio * oP:Cantidad
 *
 * // Definicion y Acceso a variables directamente
 * oP:Set("Total", oP:Get("precio") * oP:Get("CANTIDAD") )
 *
 * oP:Del("Total")         // Borro una variable
 * ? oP:IsDef("TOTAL")     // Varifico si existe una variable
 *
 * nPos := oP:GetPos("Total") // Obtengo la posición en el array
 * oP:aVars[nPos,2] := 0      // Modifico el Valor en el array directo
 *
 * aSave := oP:Save()      // Guardo las Variables
 * oP:Release()         // Borro TODAS las variables
 * oP:Restore( aSave )     // Restauro las variables
 *
 * oP:End()       // Termino
 *
 * RETURN NIL
 *
 *  EXEMPLO (Asignación Automática)
 *
 * FUNCTION MAIN()
 * LOCAL oP:=TPublic():New(.T.)
 *
 * op:nome     := "Wilson Alves"
 * op:Endereco := "Rua dos Cravos,75"
 * op:Cidade   := "Londrina-PR"
 * op:Celular  := "9112-5495"
 * op:Empresa  := "WCW Software"
 *
 * ? op:Nome,op:Endereco,op:Cidade,op:celular,op:empresa
 *
 * op:End()
 * RETURN NIL
 *
 *

# include "FiveWin.ch"

#ifdef __HARBOUR__
  # xtranslate BYNAME <V> [, <VN> ]     => ::<V> := <V> [; ::<VN> := <VN> ]
  # xtranslate BYNAME <V> DEFAULT <Val> => ::<V> := BYDEFAULT <V>, <Val>
  # xtranslate BYNAME <V> IFNONIL       => if <V> != NIL ; ::<V> := <V> ; endif
  # xtranslate BYDEFAULT <V>, <Val>     => if( <V> == NIL, <Val>, <V> )
#endif

*
* TPublic()
*
CLASS TPublic

   DATA  lAutomatic  AS LOGICAL     INIT .T.    // [WA]

   DATA  aVars       AS ARRAY       INIT NIL
   DATA  nPos        AS NUMERIC     INIT 0   READONLY // [ER]
   DATA  cName       AS CHARACTER   INIT ""  READONLY // [ER]

   METHOD New( lAutomatic )
   METHOD End()      INLINE ::Release()

   METHOD Add( cName, xValue )
   METHOD Del( cName )
   METHOD Get( cName )
   METHOD Set( cName, xValue )

   METHOD GetPos( cName )

   METHOD Release()
   METHOD IsDef( cName )

   METHOD Clone()    INLINE aClone( ::aClone )
   METHOD nCount()      INLINE Len( ::aVars )

   METHOD Save()     INLINE aClone( ::aVars )
   METHOD Restore( aVars ) INLINE ::aVars := aClone( aVars )

#ifdef __HARBOUR__
   ERROR HANDLER OnError( uParam1 )
#else
   ERROR HANDLER OnError( cMsg, nError )
#endif

ENDCLASS

*
*  TPublic:New()
*
METHOD New( lAutomatic ) CLASS TPublic // [WA]

   ::aVars := {}

   BYNAME  lAutomatic DEFAULT .T.   // [WA]

RETURN Self

*
*  TPublic:Add()
*
METHOD Add( cName, xValue ) CLASS TPublic // [ER]

  if cName != NIL
    if (::nPos := aScan( ::aVars, { |e,n| e[1] == AllTrim(Upper(cName)) } )) != 0
      ::aVars[::nPos,2] := xValue

#ifndef __HARBOUR__                 // [WA]
    elseif Len(::aVars) < 4000      // [JJMG]
      aAdd( ::aVars, { AllTrim(Upper(cName)), xValue } )
      ::nPos := Len(::aVars)

    else
      MsgAlert("Demasiadas variables definidas para la Clase TPublic()")

#else
    else
      aAdd( ::aVars, { AllTrim(Upper(cName)), xValue } )
      ::nPos := Len(::aVars)
#endif                              // [WA]

    endif

    ::cName  := cName
  endif

RETURN Self

*
*  TPublic:Del()
*
METHOD Del( cName ) CLASS TPublic
   local nPos

   if cName != NIL
      if (nPos := aScan( ::aVars, { |e,n| e[1] == AllTrim(Upper(cName)) } )) != 0
         aDel( ::aVars, nPos )
         ::aVars := aSize( ::aVars, Len(::aVars) - 1 )

         ::nPos   := 0
         ::cName  := ""
      endif
   endif

RETURN Self

*
*  TPublic:Get()
*
METHOD Get( cName ) CLASS TPublic                  // [by ER]

   if cName != ::cName
      ::nPos   := aScan( ::aVars, { |e,n| e[1] == AllTrim(Upper(cName)) } )
      ::cName  := cName
   endif

RETURN ::aVars[::nPos,2]

*
*  TPublic:Set()
*
METHOD Set( cName, xValue ) CLASS TPublic             // [by ER]

   if cName != ::cName
      ::nPos   := aScan( ::aVars, { |e,n| e[1] == AllTrim(Upper(cName)) } )
      ::cName  := cName
   endif

   ::aVars[::nPos,2] := xValue

RETURN Self

*
*  TPublic:GetPos()                         // [by ER]
*
METHOD GetPos( cName ) CLASS TPublic

   ::cName  := cName

RETURN ::nPos := aScan( ::aVars, { |e,n| e[1] == AllTrim(Upper(cName)) } )


*
*  TPublic:Release()
*
METHOD Release() CLASS TPublic

   ASIZE(::aVars,0)
   ::cName  := ""
   ::nPos   := 0

RETURN Self

*
*  TPublic:IsDef()
*
METHOD IsDef( cName ) CLASS TPublic                // [by ER]

   local lOk := .F.

   if cName != NIL
      if (::nPos := aScan( ::aVars, { |e,n| e[1] == AllTrim(Upper(cName)) } )) != 0
         ::cName := cName
         lOk := .T.
      endif
   endif

RETURN lOk

*
*  OnError()
*
#ifdef __HARBOUR__
   METHOD OnError( uParam1 ) CLASS TPublic
      local cMsg   := __GetMessage()
      local nError := If( SubStr( cMsg, 1, 1 ) == "_", 1005, 1004 )
#else
   METHOD OnError( cMsg, nError ) CLASS TPublic
      local uParam1 := GetParam( 1, 1 )
#endif

   cMsg := Upper( AllTrim( cMsg ))

   if SubStr( cMsg, 1, 1 ) == "_"
      cMsg := SubStr( cMsg, 2 )

      if cMsg == Upper(::cName)
         ::aVars[::nPos,2] := uParam1

      elseif ( ::nPos := aScan( ::aVars, { |e,n| e[1] == cMsg } ) ) != 0
         ::cName  := cMsg
         ::aVars[::nPos,2] := uParam1

      else

         if !::lAutomatic  // [WA]
            _ClsSetError( _GenError( nError, ::ClassName(), cMsg ) )
            ::cName  := ""
            ::nPos   := 0
         else
            ::add(cmsg)
            ::aVars[::nPos,2] := uParam1
         endif
      endif
   else
      if cMsg == Upper(::cName)           // [by ER]
         RETURN ::aVars[::nPos,2]

      elseif ( ::nPos := aScan( ::aVars, { |e,n| e[1] == cMsg } ) ) != 0
         ::cName  := cMsg
         RETURN ::aVars[::nPos,2]
      else
         _ClsSetError( _GenError( nError, ::ClassName(), cMsg ) )
         ::cName  := ""
         ::nPos   := 0
      endif
   endif

RETURN NIL

// Andrade Daniel (2001-2003)

 
Saludos

Re: Usar o no variables publicas.

Posted: Thu Apr 30, 2020 9:27 am
by surGom
Bueno hace años que lo que utilizo esto, que realmente lo saque de algun colaborador de nuestro foro, y disculpas por no recordar de quien, pero me funciona perfecto
En el progama principal

Code: Select all

# include "fivewin.ch"


 memvar oApp

function main()
 
 variables locales 
 oApp := TApplication()


      oApp:habilito:=GetpvProfString("dgi","habilito",,cinit)
      oApp:dirpdf := GetpvProfString("camino","dirpdf",,cinit)
      oApp:dirdoc := GetpvProfString("camino","dirdoc",,cinit)
      oApp:curproga := GetpvProfString("camino","curproga",,cinit)
      oApp:dirfac := GetpvProfString("camino","dirfac",,cinit)
      oApp:             etc , etc

  if pasaje("variable")
      database oVar
      dbgotop()
      oApp:fecha := oVar:fechamae
      oApp:ndola := oVar:dolar
      oApp:ndola30 := oVar:dolar30
      etc, etc 
 
  endif

 

return nil


////////////////////////////////////////////////////////////////////////////////////////////////
CLASS TApplication

   DATA dirpdf INIT Space(120)
   DATA dirdoc INIT Space(120)
   DATA docvarios INIT Space(120)
   DATA usuario INIT (GetpvProfString("usuario","nombre",,(GetWinDir()+"\mega.ini")))
   DATA permiso INIT (GetpvProfString("lugares","ctasctes",,(GetWinDir()+"\mega.ini")))
   DATA permiso1 INIT ( GetpvProfString("lugares","alicuota",,(GetWinDir()+"\mega.ini")))
   DATA contador INIT (GetpvProfString("camino","contpath",,(GetWinDir()+"\mega.ini")))
   DATA privado INIT (GetpvProfString("lugares","privado",,(GetWinDir()+"\mega.ini")))
   DATA destinozip INIT (GetpvProfString("camino","zip",,(GetWinDir()+"\mega.ini")))
   DATA desOcompra INIT (GetpvProfString("camino","ocompra",,(GetWinDir()+"\mega.ini")))
   DATA correo INIT ""
   DATA puerto INIT 0
   DATA smtp INIT ""
   DATA blat INIT ""
   DATA imppdf INIT ""
   DATA imppre INIT ""
   // etc y mas etc

ENDCLASS


return nil

 
Y después en cualquier módulo que utilizo lo que hago es

Code: Select all

memvar oApp

function pepito()
 bla bla bla

            IF  ShellExecute( , "open",   ( oApp:dirfac + oCae:nombre + ".pdf" ),,, 1 ) != 2
               cldata( aObj )
               RETURN NIL
            ENDIF

 


 
Funciona bien.


Luis