Nate, are you confident in this copyComponent function? It seems like it
would just copy all the methods over as structures, just like the duplicate
function does. What about the internal variables and what if this object
extends to another component. I mean what really is an object in ColdFusion
anyway, I don't know. I suppost I could figure this out with some testing,
just wondering if you had more info.

Thanks


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Nate Nielsen
Sent: Monday, November 08, 2004 2:27 PM
To: [EMAIL PROTECTED]
Subject: RE: Object Copy


Well....  Sorta, maybe and sometimes   =)

It is a pointer to the original object, but depending on what you are going
to do with your copy, you can actually make a pointer and then delete the
original and CF will treat your pointer as an original component, although
saving the state of the pointer instance, which is now the original and not
a null pointer.  Huh?  I'll explain...

Take for example a simple cfc, test.cfc :

<cfcomponent>
<cfset init()>
<cffunction name="init">
        <cfscript>
                this.helloText = 'Hello everyone!';
        </cfscript>
</cffunction>
<cffunction name="setHelloText">
        <cfargument name="text" type="string" required="yes">
        <cfset this.helloText = arguments.text>
</cffunction>
<cffunction name="getHelloText">
        <cfreturn this.helloText>
</cffunction>
</cfcomponent>

Now lets play with a few of the pointer and copy issues under MX :

First, proving the pointer issue when a straight copy is made, and the
original is still intact.

<cfoutput>
        <cfset application.appObj = createObject("component", "test")>
        <cfset application.appObj.setHelloText("Hello Nate!")>
        <cfset request.reqObj = createObject("component", "test")>
        (1) #application.appObj.getHelloText()# -
        (2) #request.reqObj.getHelloText()# -
        <cfset request.reqObj = application.appObj>
        (3) #request.reqObj.getHelloText()# -
</cfoutput>

This will output :
(1) Hello Nate! - (2) Hello everyone! - (3) Hello Nate! -

The important thing to not here, is that on the (3)rd case, we never used
the setHelloText() method to change the text, when copying the object with
the request.reqObj = application.appObj line, we made a pointer, thus making
the request value of getHelloText() equal to that of the application value.


Now, to test the theory of the pointer changing to a duplicated instance
when the pointer is null.  (note we don't get a null pointer exception which
you would expect)

<cfoutput>
        <cfset application.appObj = createObject("component", "test")>
        <cfset application.appObj.setHelloText("Hello Nate!")>
        <cfset request.reqObj = createObject("component", "test")>
        (1) #application.appObj.getHelloText()# -
        (2) #request.reqObj.getHelloText()# -
        <cfset request.reqObj = application.appObj>
        (3) #request.reqObj.getHelloText()# -
        <cfset application.appObj = "">
        (4) #request.reqObj.getHelloText()# -
        (5) #isObject(application.appObj)#
</cfoutput>

This will output :
(1) Hello Nate! - (2) Hello everyone! - (3) Hello Nate! - (4) Hello Nate! -
(5) NO

The important thing here is (5) - the application object is no longer
allocated, and we can still output from a method in the request object, seen
in the case (4).

So, long story short, depending on what you are going to do after you create
a pointer copy, the <cfset objOne = objTwo> can give you the results you
want.

NOW, the last part of my previous message isn't getting a whole lot of
attention because I don't think I spelled out how it is useful here.  You
can actually copy functions AND the state variables within your component,
thus allowing you to create duplicate copies - not pointers, actual
instances of your components.

Might be a bit messy, but this should do the trick :

<cfscript>
        function copyComponent(componentToCopyFrom,componentToCopyInto){
                var i = 1;
                var thisElement = '';
                var keyArray = structKeyArray(componentToCopyFrom);
                for(i = 1; i lte arrayLen(keyArray); i = i + 1){
                        componentToCopyInto[keyArray[i]] =
componentToCopyFrom[keyArray[i]];
                }
                return componentToCopyInto;
        }
</cfscript>

What happens here that is particularly interesting is that after you call
the copyComponent() udf, you have a new instance of the object, AND, it also
isn't a pointer when you copy the actual elements inside the component.

Here is some sample code to prove the actual instance and not just a
pointer:


<cfoutput>
        <cfset application.appObj = createObject("component", "test")>
        <cfset request.reqObj = createObject("component", "test")>
        <cfset request.reqObj =
copyComponent(application.appObj,request.reqObj)>
        <cfset application.appObj.setHelloText("Hello Nate!")>
        <cfdump var="#request.reqObj#">
        <cfdump var="#application.appObj#">
</cfoutput>

You'll notice that after you call the setHelloText() method on the
components, the information remains separate within both of the components,
not simply a pointer to one item (and thus the same information in both
copies).    Instead you have two instances independent from one another.

If you were to take out the call to the copyComponent() udf, and instead set
a pointer with just one assignment statement, you'd see the value of
helloText remain the same, because it is a pointer :

<cfoutput>
        <cfset application.appObj = createObject("component", "test")>
        <cfset request.reqObj = createObject("component", "test")>

        <cfset request.reqObj =
copyComponent(application.appObj,request.reqObj)>
        <cfset application.appObj.setHelloText("Hello Nate!")>
        <cfdump var="#request.reqObj#">
        <cfdump var="#application.appObj#">
</cfoutput>


Sorry for the very long winded reply, but I think this is one of the
trickier subject within MX, and it's easier to explain all the different
rules and tricks with some example code.

Hope that helps!

Nate
[EMAIL PROTECTED]
http://www.webclarity.com



-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf
Of Tom Woestman
Sent: Monday, November 08, 2004 10:08 AM
To: [EMAIL PROTECTED]
Subject: RE: Object Copy

Nate,

I suspect that the assignment new = oldObject just sets the 'new' variable
to point to the oldObject object and releases the newly created object to
garbage collection as the newly created object no longer has any references
pointing at it.

If the 'duplicate' functionality will not copy the CFC you may have to write
your own method to create a new instance of the CFC and copy all associated
data to the new object.

Hope this helps,
Tom Woestman


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Monday, November 08, 2004 7:59 AM
To: [EMAIL PROTECTED]
Subject: Re: Object Copy

Have you tried creating a new object and then copying the information in the
original object into it with struct copy?

Or something like

new = createObject("component", "myObject"); new = oldObject;

one wierd thing about components and functions in cfmx is that you can
actually reference functions as variables and move them between components.
really cool, but really wierd.

for example, if you have a method named "addNewRow()" - you can do something
like :

myObj = createObject("component", "myObject"); tempVar =
myObject.myFunction; // notice its not myFunction() - no parens // now you
can dump the tempVar and you'll see it is actually a function <cfdump
var="#tempVar#">

Nate Nielsen
[EMAIL PROTECTED]


>
> From: "Daniel Elmore" <[EMAIL PROTECTED]>
> Date: 2004/11/08 Mon AM 12:05:39 CST
> To: <[EMAIL PROTECTED]>
> Subject: Object Copy
>
> What's the best way to make a deep copy of a created object, in this
> case it's of a CFC. The object is cached in the application scope
> after the "constructor" is called and is used throughout the
> application. However there are some pages where I need to change some
> of the default values that were passed into the Init function, so I
> want to copy it to the request scope. I can't tell what the duplicate
> function is doing, but it doesn't copy all the methods. I would have
thought duplicate is the answer.
>
> Thanks!
> Daniel
>
> ----------------------------------------------------------
> To post, send email to [EMAIL PROTECTED] To unsubscribe:
>    http://www.dfwcfug.org/form_MemberUnsubscribe.cfm
> To subscribe:
>    http://www.dfwcfug.org/form_MemberRegistration.cfm
>
>
>

----------------------------------------------------------
To post, send email to [EMAIL PROTECTED]
To unsubscribe:
   http://www.dfwcfug.org/form_MemberUnsubscribe.cfm
To subscribe:
   http://www.dfwcfug.org/form_MemberRegistration.cfm

----------------------------------------------------------
To post, send email to [EMAIL PROTECTED]
To unsubscribe:
   http://www.dfwcfug.org/form_MemberUnsubscribe.cfm
To subscribe:
   http://www.dfwcfug.org/form_MemberRegistration.cfm


----------------------------------------------------------
To post, send email to [EMAIL PROTECTED]
To unsubscribe:
   http://www.dfwcfug.org/form_MemberUnsubscribe.cfm
To subscribe:
   http://www.dfwcfug.org/form_MemberRegistration.cfm





----------------------------------------------------------
To post, send email to [EMAIL PROTECTED]
To unsubscribe: 
   http://www.dfwcfug.org/form_MemberUnsubscribe.cfm
To subscribe: 
   http://www.dfwcfug.org/form_MemberRegistration.cfm


Reply via email to