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


Reply via email to