Page 1 of 1

Problem with Harbour Class scopes

Posted: Fri Jul 01, 2011 9:35 am
by karweru
Hi Everyone,

Please test the following code and see if you can perhaps identify what is wrong.

#include "minigui.ch"
#include "hbclass.ch"

*------------------------------------------------------------------------------*
Function Main()
*------------------------------------------------------------------------------*

DEFINE WINDOW Win_1 ;
AT 0,0 ;
WIDTH 400 ;
HEIGHT 400 ;
TITLE 'Test' ;
MAIN

DEFINE MAIN MENU
DEFINE POPUP 'File'
MENUITEM 'Test' ACTION Test()
END POPUP
END MENU

END WINDOW

MAXIMIZE WINDOW Win_1

ACTIVATE WINDOW Win_1

Return

*------------------------------
FUNCTION test
local oVar:=tVar():new(),aTemp,n
oVar:add("a",1)
oVar:add("b",1)
oVar:add("c",1)
oVar:add("d",1)

atemp:=ovar:list()

msgInfo(str(len(aTemp)),"a 4 Expected")

ovar:delete("c")

atemp:=ovar:list()

msgInfo(str(len(aTemp)),"Why a 3?")

return
*------------------------------

CREATE CLASS tVar

DATA aVars INIT {}

EXPORT:

Method init()
METHOD add(cVar,xVal)
METHOD delete(cVar)
METHOD list() INLINE ::aVars
ENDCLASS

METHOD init() CLASS tVar
return self

METHOD add(cVar,xVal) CLASS tvar
aAdd(::aVars,{upper(allTrim(cVar)),xVal})
return self

METHOD delete(cVar)
local n,lDeleted:=.f.
cVar:=upper(allTrim(cVar))
for n:=1 to len(::aVars)
if ::aVars[n,1]==cVar
aDel(::aVars,n)
lDeleted:=.t.
exit
endif
next n
if ldeleted
aSize(::aVars,len(::aVars)-1)
endif
return lDeleted

*--------------

Re: Problem with Harbour Class scopes

Posted: Fri Jul 01, 2011 10:28 am
by Rathinagiri
I couldn't find any problem here. What is the problem?

Re: Problem with Harbour Class scopes

Posted: Fri Jul 01, 2011 11:40 am
by karweru
Hi Rathi,

Sorry, my mistake. The code should be as below.

Note that i first read the contents on the Obj class to aTemp, then delete from the Obj. My believe is that the contents of aTemp shouldn't be affected?

#include "minigui.ch"
#include "hbclass.ch"

*------------------------------------------------------------------------------*
Function Main()
*------------------------------------------------------------------------------*

DEFINE WINDOW Win_1 ;
AT 0,0 ;
WIDTH 400 ;
HEIGHT 400 ;
TITLE 'Test' ;
MAIN

DEFINE MAIN MENU
DEFINE POPUP 'File'
MENUITEM 'Test' ACTION Test()
END POPUP
END MENU

END WINDOW

MAXIMIZE WINDOW Win_1

ACTIVATE WINDOW Win_1

Return

*------------------------------
FUNCTION test
local oVar:=tVar():new(),aTemp,n
oVar:add("a",1)
oVar:add("b",1)
oVar:add("c",1)
oVar:add("d",1)

atemp:=ovar:list()

msgInfo(str(len(aTemp)),"a 4 Expected")

ovar:delete("c")

msgInfo(str(len(aTemp)),"Why a 3?") //this is the problem.

return
*------------------------------

CREATE CLASS tVar

DATA aVars INIT {}

EXPORT:

Method init()
METHOD add(cVar,xVal)
METHOD delete(cVar)
METHOD list() INLINE ::aVars
ENDCLASS

METHOD init() CLASS tVar
return self

METHOD add(cVar,xVal) CLASS tvar
aAdd(::aVars,{upper(allTrim(cVar)),xVal})
return self

METHOD delete(cVar)
local n,lDeleted:=.f.
cVar:=upper(allTrim(cVar))
for n:=1 to len(::aVars)
if ::aVars[n,1]==cVar
aDel(::aVars,n)
lDeleted:=.t.
exit
endif
next n
if ldeleted
aSize(::aVars,len(::aVars)-1)
endif
return lDeleted

*--------------

Re: Problem with Harbour Class scopes

Posted: Fri Jul 01, 2011 12:59 pm
by Rathinagiri
This is not a problem with Harbour class.

I think this is not a problem at all. It is actually the nature of arrays!

In Harbour, arrays are passed by reference only!

Use this code even without class.

Code: Select all

FUNCTION MAIN

local aVar1 := { 1, 2, 3 }
local aVar2

aVar2 := avar1

aVar2[1] := 5

? aVar1[1]   && Here return 5 . Why ?
? aVar1[2]
? aVar1[3]

RETURN NIL
If you want not to pass the array by reference you have to use aclone function.

Please change your code to aTemp := aClone( oVar:list() )

Re: Problem with Harbour Class scopes

Posted: Fri Jul 01, 2011 4:26 pm
by karweru
Thank you so much Rathi for the excellent explanation. Now i understand, I have changed my code and it is working perfectly. Thank you so much.

Re: Problem with Harbour Class scopes

Posted: Fri Jul 01, 2011 6:38 pm
by Rathinagiri
Ok. You can change the code like this too!

METHOD list() INLINE aClone( ::aVars )