viernes, noviembre 20, 2009

Harbour VS xHarbour, Las diferencias verdaderas (Parte 5)

Referencias a variables almacenadas en arreglos (arrays).

En xHarbour el comportamiento de referencias almacendas en un arreglo es distinto a comparación con Clipper o Harbour.

En Clipper y Harbour al ejecutar la máquina virtual un código como:
         aVal[ 1 ] := 100
Limpia incondicionalmente el valor del primer elemento en el arreglo aVal y asigna su valor a 100.

xHarbour en cambio, verifica si aVal[1] es una referencia y en ese caso resuelve la referencia y entonces asigna 100 al elemento de destino.

Al ejecutar este código en la máquina virtual de Clipper y Harbour:
         x := aVal[ 1 ]
Se copia a "x" el valor exacto almacenado en aVal[1]. xHarbour primero revisa si aVal[1] es una referencia y en ese caso resuelve dicha referencia y luego copia a "x" el valor de referencia del elemento del arreglo.

Este comportamiento puede ser visto en este código:
      proc main
local p1 := "A", p2 := "B", p3 := "C"
? p1, p2, p3
p( { @p1, p2, @p3 } )
? p1, p2, p3

proc p( aParams )
local x1, x2, x3

x1 := aParams[ 1 ]
x2 := aParams[ 2 ]
x3 := aParams[ 3 ]

x1 := lower( x1 ) + "1"
x2 := lower( x1 ) + "2"
x3 := lower( x1 ) + "3"

Harbour y Clipper muestran esto
      A B C
a1 B a13
Pero xHarbour muestra esto:
      A B C
A B C
Esto no es compatible con Clipper, asi que en algunos casos esto puede causar problemas de portabilidad, por ejemplo el código anterior fue usado en Clipper como una solución para el número limitado de parámetors (32 en Clipper). Pero permite asignar directamente directamente elementos de arreglos retornados por hb_Params() y actualizar las variables correspondientes pasadas por referencia.

De cualquier forma el hecho de que xHarbour no tenga un operador "..." el cual pueda respetar referencias existentes en los parámetros pasados y que no soporte parametros por nombre en funciones con un numero variable de parámetros causa limitaciones, por ejemplo no es posible hacer código como este:
func f( ... )
local aParams := hb_aParams()
if len( aParams ) == 1
return f1( aParams[ 1 ] )
elseif len( aParams ) == 2
return f2( aParams[ 1 ], aParams[ 2 ] )
elseif len( aParams ) >= 3
return f3( aParams[ 1 ], aParams[ 2 ], aParams[ 3 ] )
endif
return 0

El cual respeta referencias en parametros pasados a la función f().

Continuará.....

2 comentarios:

Anónimo dijo...

Hola,
Solo un comentario, en la primera linea dice : "En Harbour el comportamiento de referencias almacendas en un arreglo es distinto a comparación con Clipper o Harbour. " y debe decir "En xHarbour el comportamiento de referencias almacendas en un arreglo es distinto a comparación con Clipper o Harbour. "

Espero haber contribuido, aunque sea con una "x" a esta generosa muestra de que el conocimiento debe compartirse. ;))

Saludos,

Lautaro Moreira
Osorno
Chile

Rene Flores dijo...

Lautaro:

Gracias !!!!!

Corregido