Controlar parametro pasado a un prg

155 views
Skip to first unread message

Jose Antonio Blasco

unread,
Aug 26, 2015, 7:11:07 AM8/26/15
to Comunidad de Visual Foxpro en Español
Hola a todos,
me surge el siguiente problema.  Tengo un "prg" al que le paso varios parámetros, de los que sólamente el primero es obligatorio.  Pero además este parámetro por necesidades propias debe ser una variable que se haya creado antes de la llamada al prg, y a la que se haya asignado un valor de tipo caracter, número o fecha.   
Mi pregunta es, como puedo controlar, desde el prg, que han hecho la llamada con una variable, y no con el valor directamente, es decir 

Asi     

myvar = 34
do myprg with myvar

y no asi

do myprg with 34

Gracias y un saludo.

Jose A. Blasco
Zaragoza - España
Visual FoxPro 9 SP2

"No hay camino hacia la libertad, la libertad es el camino" - Indira Gandhi
“Nunca te olvides de sonreír, porque el día que no sonrías  será un día perdido”  -  Charles Chaplin
“Todo el mundo quiere tener un amigo, pero pocos se toman la molestia de ser uno”
- Anónimo

Fernando D. Bozzo

unread,
Aug 26, 2015, 8:48:05 AM8/26/15
to Comunidad de Visual Foxpro en Español
Hola José:

Eso no lo podés distinguir, ya que el parámetro siempre recibe el valor, tanto directo como indirecto.

Veo 2 alternativas para esto:

1) Que uses un nuevo parámetro para indicar el tipo de dato que se va a enviar (si valor o variable)

LPARAMETERS tuMyVar, tcTipoMyVar, ...demás params


2) Que pases el nombre de la variable en vez de la variable, pero esto solo serviría si es privada o pública

myvar = 34
do myprg with "myvar"  && myvar debe ser pública o privada

Luego:

LPARAMETERS tuMyVar
IF VARTYPE(tuMyVar) = "C" AND TYPE(tuMyVar) = "N"
   lnValor = EVALUATE(tuMyVar)
ENDIF

....pero lo veo complicado esto y muy feo.


¿Por qué querés distinguir si se pasa un valor directo o una variable?

Jose Antonio Blasco

unread,
Aug 26, 2015, 8:56:46 AM8/26/15
to Comunidad de Visual Foxpro en Español
Te cuento, estoy preparando un prg que creará y mostrará un pequeño formulario para hacer una petición de un dato cualquiera, partiendo de un valor inicial o vacío, y que devuelva lo tecleado.

Como no es sólo para mi uso, pretendía controlar que otros compañeros la usaran de forma incorrecta, pero veo que tendré que confiar en que me hagan caso de como usarla.

Gracias por contestar Fernando.
Un Saludo.


Jose A. Blasco
Zaragoza - España
Visual FoxPro 9 SP2

"No hay camino hacia la libertad, la libertad es el camino" - Indira Gandhi
“Nunca te olvides de sonreír, porque el día que no sonrías  será un día perdido”  -  Charles Chaplin
“Todo el mundo quiere tener un amigo, pero pocos se toman la molestia de ser uno”
- Anónimo

Victor Espina

unread,
Aug 26, 2015, 10:06:47 AM8/26/15
to Comunidad de Visual Foxpro en Español
La forma correcta seria pasar un parametro por referencia:

myVar = 34
myPrg
(@myVar)
?myVar --> 35


* myprg.prg
PROCEDURE myPrg
(tuVar, tuParam1, ..., tuParamN)
 IF NOT VARTYPE
(tuVar) $ "CND"
   ERROR
"Invalid type for parameter"
   RETURN
.F.
 ENDIF
 IF VARTYPE
(tuVar) = "N"
  tuVar
= tuVar + 1
 ENDIF
ENDPROC




Otra forma (que yo particularmente prefiero para el caso especifico que tu quieres solucionar) es que tu rutina reciba un solo parametro en forma de objeto, el cual contiene todos los datos necesarios en forma de propiedades, incluyendo una con el resultado que deseas obtener.  Para este tipo de cosas, es super util mi rutina JSON (http://noiqs.com/sos/json.prg):

DO json    && Esto se hace al inicio del programa principal
LOCAL oArgs
oArgs
= json.parse("{ myVar: 34,  params: [ 'param1', 'param2', param3, ...., 'paramN' ],  result: null }")
DO
MyPrg WITH oArgs
?oArgs.result --> 35


* myprg.prg
PROCEDURE myPrg
(poArgs)
  IF NOT TYPE
("poArgs.myVar") $ "CND"
   ERROR
"Invalid type for parameter"
   RETURN
.F.
  ENDIF
  IF TYPE
("poArgs.myVar") = "N"
   poArgs
.Result = poArgs.MyVar + 1
 ENDIF
 FOR i
= 1 TO poArgs.Params.Count
   cParam
= poArgs.Params.Item[i]
 ENDFOR
ENDPROC




Saludos 

Victor Espina

Fernando D. Bozzo

unread,
Aug 26, 2015, 10:58:46 AM8/26/15
to Comunidad de Visual Foxpro en Español
Hola Victor:


El miércoles, 26 de agosto de 2015, 16:06:47 (UTC+2), Victor Espina escribió:
La forma correcta seria pasar un parametro por referencia:


Yo no diría que es "lo correcto" pasarlos por referencia, porque si no es como decir que pasarlas por valor es incorrecto, y realmente no es así, porque ambos tienen sus casos de uso.

Todos los lenguajes (C, C++, PL/SQL, etc) permiten pasar valores por valor o referencia, y realmente el uso correcto de los valores pasados por referencia, que yo conozca, son 2:

1) Cuando los parámetros devuelven valores de retorno: Lo que permite devolver uno o múltiples valores.

2) Cuando el valor que se pasa es muy grande: Por ejemplo, un string pesado cuesta más pasarlo por valor, en memoria y CPU, que pasar su posición de memoria (o sea, por referencia)

El paso de parámetros por valor tiene la ventaja de que dentro del procedimiento, hagas lo que hagas, no alterás su valor, en cambio pasándolo por referencia es un riesgo que debe ser analizado en el diseño.


Saludos!


Victor Espina

unread,
Aug 26, 2015, 12:30:24 PM8/26/15
to Comunidad de Visual Foxpro en Español
En este caso, con "correcto" me referia a lo que Jose queria hacer especificamente, que era pasar como parametro el nombre de una variable para almacenar en ella el resultado de una operacion.  En VFP, aunque es posible, en mi opinion personal no es lo correcto; la forma correcta es pasar el parametro por referencia.


Victor

Luis Alberto Guerra

unread,
Aug 26, 2015, 6:40:10 PM8/26/15
to Comunidad de Visual Foxpro en Español
Creo que Victor no ha entendido bien, lo que quiere José es saber si el valor que llegó al primer parámetro ha sido un valor literal o una variable, algo como:

miVar= 123
miFuncion(miVar)

miFuncion(123)

**************************
FUNCTION miFuncion
LPARAMETER miParam
** ¿Cómo saber si el valor de miParam vino a través de una variable o como un valor literal?
ENDFUNC
**************************

Mario López

unread,
Aug 27, 2015, 8:39:38 AM8/27/15
to Comunidad de Visual Foxpro en Español
@Jose: fijate esto, usando ASTACKINFO

---
* Muestra los parámetros con los que fué llamada una función

CLEAR

xPar1 = 10

Fx(10)                  && >> 10
Fx(10, 20, 30)            && >> 10| 20| 30
Fx(10, 20, ABS(30))        && >> 10| 20| ABS(30)
Fx(xPar1)                && >> xPar1
Fx((5+6/2+3))            && >> (5+6/2+3)

RETURN


FUNCTION Fx(xParam1, xParam2, xParam3, xParam4, xParam5)

LOCAL axStack[1], nStack, sLine

nStack = ASTACKINFO(axStack)
sLine = axStack[nStack-1, 6]     && Linea llamadora

? "Llamado con parametros: [" + GetParams(sLine) + "]"
RETURN

RETURN



* Extrae los parámetros
FUNCTION GetParams(sLin)
   
LOCAL nPos, nLvl, sCh

sRet = ""
nLvl = 0
   
FOR nPos = 1 TO LEN(sLin)
    sCh = SUBSTR(sLin, nPos, 1)
   
    DO CASE
    CASE sCh=="("
        IF nLvl==0
            sRet = ""
            sCh  = ""
        ENDIF
        nLvl = nLvl + 1
    CASE sCh==")"
        nLvl = nLvl - 1
        IF nLvl==0
            RETURN sRet
        ENDIF
    CASE sCh=="," AND nLvl==1
        sCh = "|"    && Separador
    ENDCASE
   
    sRet = sRet + sCh
NEXT
   
RETURN sRet

   
***

Saludos,
Mario
---

Víctor Hugo Espínola Domínguez

unread,
Aug 27, 2015, 12:37:45 PM8/27/15
to publice...@googlegroups.com
Genial! 👏

Saludos,
Víctor.
Lambaré - Paraguay.
"Todo lo que una persona puede imaginar, otros pueden hacerlo realidad" - Julio Verne.


Victor Espina

unread,
Aug 27, 2015, 12:47:20 PM8/27/15
to Comunidad de Visual Foxpro en Español
Esta fue la pregunta original:  

"Mi pregunta es, como puedo controlar, desde el prg, que han hecho la llamada con una variable, y no con el valor directamente..."

Solo hay una forma de hacer eso, que yo sepa: asumes que el parametro contiene el nombre de una variable, de modo que puedas verificar que la variable se ha definido y que tiene un valor aceptable, que fue la sugerencia que dio  Fernando.

Lo que yo decia es que la forma convencional (evitemos "correcta") de devolver un valor a traves de un parametro es usando parametros por referencia.  Si, en ese caso aun no se podria validar que el usuario invoco la funcion pasando una variable y no un valor directo, pero como digo, es lo "convencional".


Victor Espina

2) Asumes que el parametro es pasado por referencia

Victor Espina

unread,
Aug 27, 2015, 12:50:46 PM8/27/15
to Comunidad de Visual Foxpro en Español
Excelente Mario!

Victor Espina

Jose Antonio Blasco

unread,
Aug 28, 2015, 4:07:26 AM8/28/15
to Comunidad de Visual Foxpro en Español
!! Vaya !! , gracias a todos por responder.

Luis Alberto tiene razón.  Eso era lo que quería, pero con las respuestas de Victor y Fernando, me han dado ideas de como cambiar el proceso para asegurarme de su uso correcto.

Victor gracias por las explicaciones y ejemplos.  Y si, tu rutina JSON ya la descargue hace tiempo y la he usado en varias ocasiones.  Es genial.

Fernando, por fin he conseguido entender la diferencia entre pasar valores por valor o por referencia gracias a tu explicación.  De hecho, nunca las he pasado por referencia en rutinas propias, sólo en aquellas que he descargado compartidas por todos vosotros, y que funcionaban así.   

Muchas gracias a todos.   Habeis sido de gran ayuda.

Un saludo.

Jose A. Blasco
Zaragoza - España
Visual FoxPro 9 SP2

"No hay camino hacia la libertad, la libertad es el camino" - Indira Gandhi
“Nunca te olvides de sonreír, porque el día que no sonrías  será un día perdido”  -  Charles Chaplin
“Todo el mundo quiere tener un amigo, pero pocos se toman la molestia de ser uno”
- Anónimo

Reply all
Reply to author
Forward
0 new messages