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",firstobjectref)
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.

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

Jack
Tue Oct 24 01:38:52 CDT 2006

On Mon, 23 Oct 2006 17:17:25 -0700, Gene Wirchenko <genew@ocis.net>
wrote:

> 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",firstobjectref)
> 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.

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

Olaf
Tue Oct 24 04:11:15 CDT 2006

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.






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

Bernhard
Tue Oct 24 05:45:57 CDT 2006

Hi Olaf,

> 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

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

Olaf
Tue Oct 24 08:43:09 CDT 2006

> 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.






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

Bernhard
Tue Oct 24 09:47:55 CDT 2006

Hi Olaf

> 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

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

Olaf
Tue Oct 24 10:08:37 CDT 2006

> 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.



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

swdev2
Tue Oct 24 12:01:29 CDT 2006

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

.



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

Gene
Tue Oct 24 11:45:57 CDT 2006

"swdev2" <wsanders@dotnetconversions.bob.com> wrote:

>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.

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

Lew
Tue Oct 24 15:13:28 CDT 2006

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



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

Gene
Tue Oct 24 17:49:57 CDT 2006

[attributions corrected]

"Lew Schwartz" <lschwartz@sionline.com> wrote:

>[Gene Wirchenko:]

>> (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:

My wording was a bit too strong, but you missed the point that
there can be two or more second objects. The purpose of the first
object is to collect all of the data from the second objects (report
programs). The lifetime of the first object has be at least as long
as all of the second objects. It is the caller to the report programs
that knows how many reports there will be combined.

[snip]

Sincerely,

Gene Wirchenko

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

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

Lew
Tue Oct 24 19:06:31 CDT 2006

Still not a problem

local oFirst
oFirst = createobject("firstclass")
* You may not even need the maintain obj references to the other classes.
eg:
createobject("secondclass",oFirst)
createobject("thirdclass",oFirst)
etc....

oFirst is exposed to everything else & will disappear at the end of this
prg. Make sure to set the property references to null in the destroy methods
of second & third class.
HTH
-Lew
"Gene Wirchenko" <genew@ocis.net> wrote in message
news:it5tj21sjh5v1dlmqv798gh75ies7vuad1@4ax.com...
> [attributions corrected]
>
> "Lew Schwartz" <lschwartz@sionline.com> wrote:
>
>>[Gene Wirchenko:]
>
>>> (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:
>
> My wording was a bit too strong, but you missed the point that
> there can be two or more second objects. The purpose of the first
> object is to collect all of the data from the second objects (report
> programs). The lifetime of the first object has be at least as long
> as all of the second objects. It is the caller to the report programs
> that knows how many reports there will be combined.
>
> [snip]
>
> Sincerely,
>
> Gene Wirchenko
>
> Computerese Irregular Verb Conjugation:
> I have preferences.
> You have biases.
> He/She has prejudices.



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

Gene
Tue Oct 24 20:01:47 CDT 2006

"Lew" <lew@fastmail.fm> wrote:

>Still not a problem
>
>local oFirst
>oFirst = createobject("firstclass")
>* You may not even need the maintain obj references to the other classes.
>eg:
>createobject("secondclass",oFirst)
>createobject("thirdclass",oFirst)
>etc....
>
>oFirst is exposed to everything else & will disappear at the end of this
>prg. Make sure to set the property references to null in the destroy methods
>of second & third class.

I do know about createobject(). I have been using it for years.
Your approach above is about what I will be doing.

[snipped previous]

Sincerely,

Gene Wirchenko

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