dbTalk Databases Forums  

VFP 9: Objects: Call by Reference / Call by Value

comp.databases.xbase.fox comp.databases.xbase.fox


Discuss VFP 9: Objects: Call by Reference / Call by Value in the comp.databases.xbase.fox forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Gene Wirchenko
 
Posts: n/a

Default VFP 9: Objects: Call by Reference / Call by Value - 10-23-2006 , 07:17 PM






SET UDFPARMS does not cover the case of a parameter being an
object. I can not think of where else to check. (@ does not do it
<G>.)

I need to pass an object to another object. In the processing
that the second object does, the first object's state will normally
change. The object pointed to by the parameter will not. I realised
that I am not sure how to do this.

(The first object is a data collector. I can not instantiate the
first object in the second object as the first object's lifetime may
have to be more than one second object lifetime.)

Illustrative snippets:

firstobjectref=createobject("firstobject" ... )
secondobjectref=createobject("secondobject",firsto bjectref)
secondobjectref.somesecondmethod(...)

define class secondobject as ...
...
procedure init
lparameters ... firstobj
...
this.firstobj=firstobj
...
endproc
procedure somesecondmethod
this.firstobj.somefirstmethod(...)
but not
this.firstobj=...

Is the createobject() correct, or should it be
... @firstobjectref ...
?

How does the answer change if the object pointed to by the
parameter could change (and it is to be passed back to the caller)?

Any other gotchas to watch for?

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
I have preferences.
You have biases.
He/She has prejudices.

Reply With Quote
  #2  
Old   
Jack Jackson
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 01:38 AM






On Mon, 23 Oct 2006 17:17:25 -0700, Gene Wirchenko <genew (AT) ocis (DOT) net>
wrote:

Quote:
SET UDFPARMS does not cover the case of a parameter being an
object. I can not think of where else to check. (@ does not do it
G>.)

I need to pass an object to another object. In the processing
that the second object does, the first object's state will normally
change. The object pointed to by the parameter will not. I realised
that I am not sure how to do this.

(The first object is a data collector. I can not instantiate the
first object in the second object as the first object's lifetime may
have to be more than one second object lifetime.)

Illustrative snippets:

firstobjectref=createobject("firstobject" ... )
secondobjectref=createobject("secondobject",firsto bjectref)
secondobjectref.somesecondmethod(...)

define class secondobject as ...
...
procedure init
lparameters ... firstobj
...
this.firstobj=firstobj
...
endproc
procedure somesecondmethod
this.firstobj.somefirstmethod(...)
but not
this.firstobj=...

Is the createobject() correct, or should it be
... @firstobjectref ...
?

How does the answer change if the object pointed to by the
parameter could change (and it is to be passed back to the caller)?

Any other gotchas to watch for?

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
I have preferences.
You have biases.
He/She has prejudices.
I don't think @ works any differently if a parameter contains an
object reference or any other type of value.

procedure xx
lparameters xParm

xParm = 3

return
endproc

yy = 'a'
xx(yy)
* at this point yy still contains 'a'

yy = 'a'
xx(@yy)
* at this point yy contains 3

Call by reference simply makes any changes to the parameter (not to a
variable to which you have copied the parameter) visible in the
calling procedure.

Unless your Init method changes the parameter variable:

firstobj = ...

then there is no reason to pass the parameter by reference.


Reply With Quote
  #3  
Old   
Olaf Doschke
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 04:11 AM



Hi Gene,

objects are passed by reference anyway, no
need to use @ or SET UDFPARMS.

So your suggested code would work.

You can't inn fact pass an object by value,
because that would mean, vfp would need
to create a copy of a perhaps very complicated
structure and eg in case of passing THISFORM
by val, how should the dataenvironment be
treated? Create a new datasession or not,
etc. pp.

Because of the unpredictable nature of an
object and the problems, that may arise in
copying it, objects are always passed by ref.

Bye, Olaf.






Reply With Quote
  #4  
Old   
Bernhard Sander
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 05:45 AM



Hi Olaf,

Quote:
You can't inn fact pass an object by value,
Objects are always handled via a reference.
Such a reference could be passed by ref or by value.
In both cases, there will be no second copy of the object.
When passed by ref, there is only one object reference.
When passed by val, then within the procedure there exists a second copy of the
object reference.

An object variable is treated as any other variable. Its contents is a reference
to an object, that's all.
One says: the object "loObj"... This is not exactly true. The object can live
without the variable loObj, as long as there exists at least one reference to
this object.

loObj = createObject(...)
AddProperty(loObj, "someproperty", 1)

?loObj.someproperty && 1
someproc(loObj)
* loObj still contains a reference to the object
?loObj.someproperty && 2

someproc(@loObj)
* now loObj contains 5 instead of the former reference to the object.
* if loObj had the only reference to the object, the object will be destroyed.

?loObj.someproperty && error
?loObj && 5

PROCEDURE someproc(txPara)
txPara.someproperty = txPara.someproperty + 1
txPara = 5
ENDPROC

Regards
Bernhard Sander


Reply With Quote
  #5  
Old   
Olaf Doschke
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 08:43 AM



Quote:
Objects are always handled via a reference.
Such a reference could be passed by ref or by value.
I see the point, okay. But what you do to the parameter
holding the passed in object is rather unusual.

As you showed yourself the property of loObj is
modified whatsoever, and I think that is more important
to Gene or anyone interested.

And you might never want to pass in object references
by reference (with @), for the safety to have them intact
after the call, only modified, but not destroyed or replaced.

Bye, Olaf.







Reply With Quote
  #6  
Old   
Bernhard Sander
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 09:47 AM



Hi Olaf

Quote:
I see the point, okay. But what you do to the parameter
holding the passed in object is rather unusual.

As you showed yourself the property of loObj is
modified whatsoever, and I think that is more important
to Gene or anyone interested.

And you might never want to pass in object references
by reference (with @), for the safety to have them intact
after the call, only modified, but not destroyed or replaced.
My main intent was to clarify the difference between the object and the
referencing variable and to show, that there is no magic with these object
variables.

A use case for "by ref" object parameters might be a factory routine which
returns one or more objects via parameter.


Regards
Bernhard Sander


Reply With Quote
  #7  
Old   
Olaf Doschke
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 10:08 AM



Quote:
A use case for "by ref" object parameters might be a factory routine which
returns one or more objects via parameter.
of course, yes. In fact I did that in a situation where I wanted
each and every method of a class to return nothing more nor
less than an error code. All other things needed to be returned
by passing in by ref parameters or via created cursors.

But then you normally will pass in a variable holding .null. so
far, eg:

local loNewObject
loNewObject = .null.
oFactory.create(@loNewObject,classname,...)

=> loNewobject is created within factory
and the by ref parameter is set to that object.

That's useful of course, but it's the other way around
compared to passing in an object and letting that get
destroyed within. Is there a garbage destruction plant
pattern? ;-)

---

You can also simply make the new Object being
the return value, and don't need to pass in a reference
to the var, which later should hold the object reference,
but simply do like we all are used to already by
Createobject() etc.:

local loNewObject
loNewObject = oFactory.create(cClassname,...).

where oFactory.create() is somthing like:
lparam tcClassname, ...
....
....
....
Return CreateObject(lcSomeClassname)

Bye, Olaf.




Reply With Quote
  #8  
Old   
Gene Wirchenko
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 11:45 AM



"swdev2" <wsanders (AT) dotnetconversions (DOT) bob.com> wrote:

Quote:
Hey Gene.
another approach would be to have the object live in an object hierarchy.
I use a top level oApp object, and attach other objects to it.
The scope then is global to everything.
I do have a rudimentary app object. I prefer to keep the scope
as local as I can. In my case, I have to combine two reports together
(simple append). The object that I pass to each report receives the
pages of output. Since I am combining reports, it can not be that the
reports initialise the object.

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
I have preferences.
You have biases.
He/She has prejudices.


Reply With Quote
  #9  
Old   
swdev2
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 12:01 PM



Hey Gene.
another approach would be to have the object live in an object hierarchy.
I use a top level oApp object, and attach other objects to it.
The scope then is global to everything.

ie -
oApp.oConn

then instead of passing the object INTO your 2nd object - I can reference it
directly ...

[some code]
lcConnHandle = oApp.oConn.ConnectionHandle

or ...
in the init of your 2nd object, you can list the parameters like you want ..
parms1, parms2, etc
then call the object like this -
lo_newObject = secondObject("george",oApp.Oconn)


In my mind, its a scoping issue. My work around, ages past, was to have an
object hierarchy.
Things in the oApp object were perceived to be 'global' in scope .
I can add in objects to the oApp object on the fly, as needed.

hth - regards [Bill]

--
===================
William Sanders / EFG VFP / mySql / MS-SQL
www.efgroup.net/vfpwebhosting
www.terrafox.net www.viasqlserver.net

..



Reply With Quote
  #10  
Old   
Lew Schwartz
 
Posts: n/a

Default Re: VFP 9: Objects: Call by Reference / Call by Value - 10-24-2006 , 03:13 PM



When you create an object, VFP maintains it in an object pool and keeps it
as long as there are any references to it. It actually counts the
referenecs. This is sop in the oop world.

All you ever get is an object reference, never the object itself. There's no
more overhead in passing a reference to an entire oop oriented application
than there is to a line object. By val/ by ref has *nothing* to do with
this.

There's nothing wrong with your code as long as you understand that the
line:

this.firstobj=firstobj

creates a second reference to the same object. You'll create problems if you
don't issue a

this.firstobj = null && destroy method is a good place for this.

because the internal reference counter is at 2 and you & fox will lose track
of the ability to get rid of firstobj if fox thinks there's an outstanding
reference which you've lost track of when you let secordobj evaporate. This
is an oopy no-no.

It's certainly possible for you to find a way for this.firstobj to point to
a diffenent object, for each oThing in ... depends on this behavior.

You wrote:

I need to pass an object to another object. In the processing
that the second object does, the first object's state will normally
change. The object pointed to by the parameter will not. I realised
that I am not sure how to do this.

-> The object pointed to by the parameter certainly will change. Both the
parameter and this.firstobj point to the same, identical object in the
object pool. No additional or temporary copies are made.

(The first object is a data collector. I can not instantiate the
first object in the second object as the first object's lifetime may
have to be more than one second object lifetime.)

-> Yes, you can instantiate the first object in the method code of the
second. That's exactly what createobject(), newobject() and their
corresponding methods do. How else would you get a reference to the created
object? Consider:

oPerson = CreatePersonObject("Sam")
? oPerson.Name

function CreatePersonObject
lparameters cName
local oTemp
oTemp = createobject("Empty")
Addprop(oTemp,"CLASS","PERSON")
Addprop(oTemp,"Name",cName)
return oTemp
endfunc

Fox objects are *entirely* trustworthy if you understand what you're doing.

-Lew



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.