Page 1 of 2

Migracion a Harbour

PostPosted: Thu Mar 09, 2017 1:04 pm
by hmpaquito
Hola a todos,

Estoy intentando migrar un programa a Harbour.
Pero en el mismo codigo donde xHarbour trabaja bien, Harbour, a veces, se le va la cabeza y da error.

Es algo relacionado a parametros y codeblocks. Se me ha dado ya algunas veces.
Un parametro, en este caso array, no recuerdo si de otro tipo tambien da problema, llega un momento que pierde su valor y se pone a NIL

El escenario para producir el error es mas o menos asi:

Code: Select all  Expand view
FUNCTION Noname()
Local nI
Local a:= {"algo"}
FOR nI:= 1 TO 100
   NoName2(a)
NEXT
RETURN NIL

FUNCTION NoName2(a)
Local b:= {|| msginfo( Str(len(a)) ) }  // <----- Aqui la variable a, llegado un momento determinado, sin razón alguna, tiene el valor NIL
Eval(b)
RETURN NIL 


En cambio, si el parametro lo asigno a local, el problema desaparece.

Code: Select all  Expand view
FUNCTION Noname()
Local nI
Local a:= {"algo"}
FOR nI:= 1 TO 100
   NoName2(a)
NEXT
RETURN NIL

FUNCTION NoName2(aPar)
Local a:= aPar           // <--- Esta asignacion del parametro renombrado como variable local hace que ya no se produzca error.
Local b:= {|| msginfo( Str(len(a)) ) }
Eval(b)
RETURN NIL 

Mayormente lo pregunto por si a alguien le ha pasado.

Saludos

Re: Migracion a Harbour

PostPosted: Thu Mar 09, 2017 1:21 pm
by joseluisysturiz
Buen dia, prueba quitando la VAR LOCAL 'nI' de la funcion NoName2() que es igual al del FOR aunque esten en funciones diferentes, es solo una idea, hay cosas de programacion que son tontas y a veces son las mas dificiles de ver o entender...es lo unico que se me ocurreo, saludos... :shock:

Re: Migracion a Harbour

PostPosted: Thu Mar 09, 2017 1:35 pm
by hmpaquito
joseluisysturiz wrote:Buen dia, prueba quitando la VAR LOCAL 'nI' de la funcion NoName2() que es igual al del FOR aunque esten en funciones diferentes, es solo una idea, hay cosas de programacion que son tontas y a veces son las mas dificiles de ver o entender...es lo unico que se me ocurreo, saludos... :shock:



Gracias por tu interés pero eso es solo un error en la preparacion del codigo de demo. Voy a ponerlo bien.

Estoy casi seguro que el error está en Harbour, porque con xHarbour no me ocurre. Ademas la situacion se me ha dado en diferentes procesos, y ademas el arreglo para que trabaje, es declarando una local para que coja el valor del parametro, que en xHarbour/ Harbour/ Clipper, es equivalente, o deberia serlo, a la declaracion de parametros entre los parentesis.

Re: Migracion a Harbour

PostPosted: Thu Mar 09, 2017 1:42 pm
by karinha
Code: Select all  Expand view

#include "FiveWin.ch"

MEMVAR nI

FUNCTION Noname()

   Local a:= {"algo"}

   FOR nI:= 1 TO 10 // 100
      NoName2(a)
   NEXT

RETURN NIL

FUNCTION NoName2(a)

   Local b:= {|| msginfo( Str(len(a)) ) }  // 1

   Eval(b)

RETURN NIL
 

Re: Migracion a Harbour

PostPosted: Thu Mar 09, 2017 2:41 pm
by cnavarro
Tu primera version no me ha dado ningún problema, pero puedes probarlo asi?

Code: Select all  Expand view


FUNCTION Noname()
Local nI
Local a:= {"algo"}
FOR nI:= 1 TO 100
   NoName2(a)
NEXT
RETURN NIL

FUNCTION NoName2(aPar)
Local b:= { | a | msginfo( Str(len(a)) ) }
Eval(b, aPar)
RETURN NIL

 

Re: Migracion a Harbour

PostPosted: Thu Mar 09, 2017 5:26 pm
by José Luis Sánchez
Hola,
me suena a un tema de 'detached locals', mira esta entrada de un viejo bloguero http://webcache.googleusercontent.com/s ... clnk&gl=es El artículo ha sido borrado, tienes que buscarlo en el caché de google.

Saludos,

Re: Migracion a Harbour

PostPosted: Fri Mar 10, 2017 11:47 am
by hmpaquito
Hola a todos,

Os agradezco sinceramente vuestra ayuda.

Estoy casi seguro que hay un problema con Harbour. ¿ Por qué lo creo así ? Pues porque, como hace el ejemplo 2, simplemente declarando el parametro como variable Local el problema desaparece.
Es una pena que no haya podido encontrar un ejemplo autocontenido que lo muestre, aunque los ejemplos si reflejan el esquema en donde se da el problema: llamadas reiteradas a funcion con parametro y ese parametro es usado en un codeblock dentro de la funcion llamada.

José Luis,

He visto el enlace. Muy bueno, gracias. Pero para resumir, lo que dice el articulo es que Clipper y xHarbour tienen un pequeño fallo con las detached locals, que Harbour SI tiene corregido. Yo en cambio digo que el fallo lo tiene Harbour.
PD. La encuesta: buenisima, pero ¿ para cuando un articulo con las conclusiones (tuyas) de la encuesta ? :D

Saludos

Re: Migracion a Harbour

PostPosted: Sat Mar 11, 2017 1:49 pm
by horacio
Con tu ejemplo no he podido reproducir el error, lo he echo iterar un millón de veces y funciona perfectamente.

Saludos

Re: Migracion a Harbour

PostPosted: Sun Mar 12, 2017 11:11 am
by hmpaquito
horacio wrote:Con tu ejemplo no he podido reproducir el error, lo he echo iterar un millón de veces y funciona perfectamente.

Saludos


Horacio,

Gracias por tu prueba. Yo tampoco he conseguido un ejemplo autocontenido del mal funcionamiento.

Las situaciones reales donde el problema se da son trozos de código más complejos que los expuestos, pero que siguen el mismo esquema.
Sé que el problema debe existir porque, como ya comenté, se soluciona simplemente declarando el parámetro como una variable LOCAL y asignándole el valor.

Saludos

Re: Migracion a Harbour

PostPosted: Sun Mar 12, 2017 10:28 pm
by xmanuel
No sé si es el mismo caso que me pasó a mi hace un tiempo...

Por casualidad tienes alguna función hecha en lenguaje C... le pasas algún valor por referencia?

Aunque no me gusta la solución que te voy a dar, a mi me funcionó.

Mira haz la siguiente modificacion:
Code: Select all  Expand view

static a // <--- Declara como static antes de la primera funcion, y no tendrás que psarla porque será visible en todo el PRG
FUNCTION Noname()
Local nI
a:= {"algo"} // <--- Solo hay que darle el valor
FOR nI:= 1 TO 100
   NoName2() // <--- No hay que pasarla
NEXT
RETURN NIL

FUNCTION NoName2()  // <--- No hay que pasarla
Local b:= {|| msginfo( Str(len(a)) ) }  // <----- Aqui la variable a, llegado un momento determinado, sin razón alguna, tiene el valor NIL
Eval(b)
RETURN NIL
 

Yo tenia una función hecha en C que recibía la variable por referencia y cuando entraba en un GET perdia la referencia y con esto se solucionaba :D

Re: Migracion a Harbour

PostPosted: Mon Mar 13, 2017 8:07 am
by hmpaquito
Hola Manuel,

Gracias por tu interés.

La solución que voy dando cuando encuentro el problema es declarar una variable LOCAL que tome el valor del parámetro.

En general, salvo prisas, a veces tambien por clarificacion del codigo, procuro no usar variables STATIC porque impiden la reentrada; es decir, darian problemas si se entrara mas de una vez al fuente donde habitan.

Saludos

Re: Migracion a Harbour

PostPosted: Tue Mar 14, 2017 12:52 am
by horacio
Yo utilizo variables static y no he tenido problemas. Muchas de mis rutinas utilizan variables static con el mismo nombre en distintas módulos y no me han generado errores. Puedes aclarar tu afirmación. Gracias.

Re: Migracion a Harbour

PostPosted: Tue Mar 14, 2017 8:16 am
by hmpaquito
horacio wrote:Yo utilizo variables static y no he tenido problemas. Muchas de mis rutinas utilizan variables static con el mismo nombre en distintas módulos y no me han generado errores. Puedes aclarar tu afirmación. Gracias.



https://groups.google.com/forum/?fromgr ... xJYnlma9EJ

Re: Migracion a Harbour

PostPosted: Tue Mar 14, 2017 10:59 am
by Carlos Mora
Paquito,

Creo que hay una muy mala interpretación de los eventuales problemas con las STATICs. Cuando Przemek se refiere a los problemas de reentrada no quiere decir que vuelvas a llamar a alguna función del prg , sino que EN EL CONTEXTO DE MULTITASKING, mientras una función se está ejecutando y alterando el valor de la STATIC, otro hilo podría entrar EN LA MISMA FUNCION SIMULTANEAMENTE y alterar el valor de la misma STATIC.
Por poner una analogía, imaginate el problema que tendríamos si pudiésemos acceder a modificar registros en una base de datos compartida sin necesidad de bloqueo. Pues lo mismo pero con variables de memoria STATIC, y siempre en el contexto de MT, cosa que no suele suceder (al menos yo no programo con MT).
La sugerencia de Przemek es utilizar técnicas más avanzadas para encarar los problemas de STATIC, pero problemas que no tenemos a menos que estemos usando MT. De hecho el mismo, en su respuesta, explica que usa STATICs en una librería de pdfs. Y como técnica más avanzada para evitar esto de las STATICs, se pueden usar variables o DATAs de CLASE (CLASS VARS)
Un ejemplo más en favor de las STATICs: Si miramos el código preprocesado de una clase cualquiera, incluyendo cualquiera de las de FW, verás que el comando CLASS <myclass> genera una funcion QUE INCLUYE UNA STATIC. Lo puedes corroborar en el 'hbclass.ch', en la definición del comando.

PD: Creo que el nombre "Przemek" significa "Paquito" en polaco :D

Re: Migracion a Harbour

PostPosted: Tue Mar 14, 2017 12:12 pm
by hmpaquito
Estimado Carlos,

Entiendo que te refieres a Viktor. Przemek no aparece en el hilo.

Por otra parte. Imagínate un extracto de artículos vendidos a todos los clientes. Estando sobre una linea, pulsas y te muestra un nuevo extracto con los articulos vendidos al cliente de la linea.

Ahí hay reentrada, incluso en modo ST. El uso de static en esas condiciones dará lugar a errores, sino se lleva cuidado.

Saludos

PD 1. Si el santo de Przemyslaw se puede celebrar el 13 de Abril, el 4 de Septiembre, el 10 de Octubre y el 30 de Octubre, el 10 de Octubre coincide con la fecha de la onomástica de San Francisco de Borja.
PD 2. Ya tengo en marcha la exportacion mysql rapida y desatendida solo con codigo prg. :)