Don't know if this will help this topic or not but I recently case where I
had to have a deep copy of a CFC. I did some poking around the boards and
found several threads referring to this issue and found a proposed
duplicator component that I took and modified for my use. The code follows
if it would be helpful to you. Its pretty much a hack but it works for me
=).
Good Luck !
Dirk
*******************************************************************
Example Code Usage:
<cfscript>
duplicator =
CreateObject('component','#request.mapCFC#/com/cfcDuplicator');
duplicator.init();
REQUEST.order = duplicator.copyComponent(sessionOrder);
REQUEST.order.cart = duplicator.copyComponent(sessionOrder.cart);
</cfscript>
cfcDuplicator.cfc
------------------------------
<cfcomponent>
<CFSET this.iterations = 0>
<CFSET this.maxIterations = 23>
<cffunction name="init" access="public" returntype="any" output="true">
</cffunction>
<cffunction name="clone" access="public" returntype="any" output="false">
<cfargument name="myItem" required="yes">
<CFIF this.iterations GT this.maxIterations>
<cfoutput>Depth of #this.maxIterations# exceeded.</cfoutput><br>
<CFABORT>
</CFIF>
<cfoutput>
<CFSET returnValue = "">
<CFIF IsSimpleValue(myItem)>
#myItem#<br>
<CFSET returnValue = myItem>
<CFELSEIF IsArray(myItem)>
IsArray<br>
<CFSET returnValue = _dupArray(myItem)>
<CFELSEIF REQUEST.isCFC(myItem)>
<CFSET returnValue = copyComponent(myItem)>
<CFELSEIF IsStruct(myItem)>
IsStruct<br>
<CFSET returnValue = _dupStruct(myItem)>
</CFIF>
</cfoutput>
<CFRETURN returnValue>
</cffunction>
<cffunction name="copyComponentNew" access="public" returntype="any"
output="false">
<cfargument name="myComponent" required="yes">
<cfset var varscope=getPageContext().getVariableScope()>
<cfset var property="">
<cfset var
dup=createObject("component",getMetaData(arguments.myComponent).name)>
<cfloop collection="#myComponent#" item="property">
<cfif not IsCustomFunction(myComponent[property])>
<CFIF IsSimpleValue(myComponent[property])>
<CFSET "dup.#property#" = myComponent[property]>
<CFELSEIF REQUEST.isCFC(myComponent[property])>
<cfoutput>
<br>Cloning.....#GetMetaData(myComponent[property]).name#<br>
</cfoutput>
<CFSET element = clone(myComponent[property])>
<CFSET "dup.#property#" = element>
<CFELSEIF IsArray(myComponent[property])>
<cfoutput>
Duplicating Array.....#property#<br>
<!--- <CFDUMP var="#getMetaData(myComponent[property])#"> --->
</cfoutput>
<!--- <cfdump var="#myComponent[property]#"> --->
<!--- <CFSET temp = _dupArray(myComponent[property])> --->
<CFSET "dup.#property#" = _dupArray(myComponent[property])>
<CFELSE>
<cfoutput>
Duplicating.....#property#<br>
</cfoutput>
<cfset dup[property]=duplicate(myComponent[property])>
</CFIF>
</cfif>
</cfloop>
<cfreturn dup>
</cffunction>
<cffunction name="copyComponent" access="public" returntype="any"
output="false">
<cfargument name="myComponent" required="yes">
<cfset var varscope=getPageContext().getVariableScope()>
<cfset var property="">
<cfset var
dup=createObject("component",getMetaData(arguments.myComponent).name)>
<cfloop collection="#myComponent#" item="property">
<cfif not IsCustomFunction(myComponent[property])>
<cfset dup[property]=duplicate(myComponent[property])>
</CFIF>
</cfloop>
<cfreturn dup>
</cffunction>
<cffunction name="_dupArray" access="public" returntype="array"
output="false">
<cfargument name="myArray" type="array" required="yes">
<CFSET newArray = ArrayNew(1)>
<cfloop index="idx" from="1" to="#ArrayLen(myArray)#">
<cfoutput>
#idx#<br>
</cfoutput>
<CFSET newArray[idx] = clone(myArray[idx])>
</CFLOOP>
<CFRETURN newArray>
</cffunction>
<cffunction name="_dupStruct" access="public" returntype="struct"
output="false">
<cfargument name="myStruct" type="struct" required="yes">
<CFSET newStruct = StructNew()>
<cfloop collection="#myStruct#" item="item">
<cfscript>
duplicator = CreateObject('component',
'#request.mapCFC#/com/webom/cfcDuplicator');
duplicator.init();
</cfscript>
<CFSET "newStruct.#item#" = duplicator.clone(Evaluate("myStruct.#item#"))>
<!--- <CFOUTPUT>
newStruct.#item# - <CFDUMP var="#Evaluate("myStruct.#item#")#"><br>
</CFOUTPUT> --->
</CFLOOP>
<CFRETURN newStruct>
</cffunction>
<cffunction name="_setAttribute" access="public" returntype="void"
output="false">
<cfargument name="name" type="string" required="true">
<cfargument name="value" type="any" required="true">
<cfset getPageContext().setAttribute(arguments.name,arguments.value)>
</cffunction>
</cfcomponent>
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] On Behalf Of Daniel Elmore
> Sent: Tuesday, November 09, 2004 12:13 PM
> To: [EMAIL PROTECTED]
> Subject: RE: Object Copy
>
> 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
>
>
>
----------------------------------------------------------
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