Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 412
  • Last Modified:

Duplicate Object

I know this is a well known issue, that I can't duplicate a CFC instance. It converts the object into structs. But has anyone written a cfc duplicate component or custom tag??
0
elmoredaniel
Asked:
elmoredaniel
  • 13
  • 11
  • 4
1 Solution
 
CFDevHeadCommented:
can you give an example of this
cfc duplicate component or custom tag
0
 
elmoredanielAuthor Commented:
Example? I don't know, if I had that I wouldn't need to ask for one. It would work something like this:

<!--- create a component instance --->
<cfset object1 = createobject("component","thecfc")>

<!--- use duplicator to create a deep copy --->
<cfset duplicator = createobject("component","cfcduplicator")>
<cfset object2 = duplicator.createDuplicateObject("object1")>
0
 
CFDevHeadCommented:
what would be the point of coping a CFC
0
How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

 
CFDevHeadCommented:
Here check out this site, it has example of how to build CFCs dynamically http://cfoop.com/project.cfm?view=EMF
Maybe that will help.

I am still unsure of what it is you’re trying to do?

If you’re trying to make another instance of a CFC you could just go like this
<cfset object1 = createobject("component","thecfc")>
<cfset object2 = object1 >

If you’re trying get a cfc to actually have a cfc copy another cfc line for line then I can't help you.
0
 
elmoredanielAuthor Commented:
There are alot of uses for this functionalty. Perhaps your not the right person for this question. A common one is to use a design pattern where a cfc is cached in the Application scope loaded with default parameters (from the "constructor") and then copy the cfc into a local scope when a page requires special handling, in which one of those values needs to change.
0
 
elmoredanielAuthor Commented:
Your code doesn't make another instance, it makes a pointer.
0
 
Tacobell777Commented:
to make another instance you would do

<cfset object1 = createobject("component","thecfc")>

<cfset object2 = createobject("component","thecfc")>

Not sure why you would first want to instantiate the object and then create a duplicate of it?

You could pass the CFC into another object could you not (polymorphism)?
0
 
elmoredanielAuthor Commented:
The question was not how to make a duplicate object from a cfc; it was how to make a duplicate object from a cfc INSTANCE, ie another created object. Apparently my question is beyond the scope of these forums. To use polymorphism in that way I would have to create a duplicate method for every cfc. This is not very practical.
0
 
CFDevHeadCommented:
In response to your answer "common one is to use a design pattern where a cfc is cached in the Application scope loaded with default parameters (from the "constructor") and then copy the cfc into a local scope when a page requires special handling, in which one of those values needs to change." to my question

why wouldn't you just recall the function

example

<cfset application.object1 = createobject("component","thecfc")>

<cfset local.object2 = createobject("component","thecfc")>
0
 
Tacobell777Commented:
Yeah maybe we are all a bit to dumb here..
0
 
elmoredanielAuthor Commented:
Because I said that object is loaded with parameters, both for the instantiated cfc and all the cfcs it extends to. This is OOP 101. I would have to recreate my Init ("constructor") call, instead of just using my setter methods to change the values that differ.
0
 
elmoredanielAuthor Commented:
Thanks for your time. Don't worry about it. I love these forums, tons of very bright folks. But when it comes to ColdFusion help, they are lacking.
0
 
Tacobell777Commented:
Yeah we know nothing about OOP mate, sorry better get back to JAVA and don't ask difficult questions in the CF forum..
0
 
elmoredanielAuthor Commented:
Difficult question, Ha Ha, it's evangelized thinking like that which keeps ColdFusion from being deployed for larger applications. :)
0
 
Tacobell777Commented:
I wasn't serious!

And I also don't deserve the points - because it wasn't an answer, I appreciate you giving them, but you better get a refund on them...
0
 
elmoredanielAuthor Commented:
It's cool TacoBell, take the points for your time. The points are pretty cheap, sometimes I worry about inflation and experts losing the incentive to man the forums. I'm sure this is being monitored though, I hope anyway. :-)
0
 
Tacobell777Commented:
I appreciate your generousity, but the fact of the matter is, what I provided is not an answer, and when people search for an answer and find this post they will be very dissapointed..

I actually do know about OOP, but you sort of came to this forum with the attitude that we would not have answer or know anything about OOP in ColdFusion.. Some of us actually read books about OOP ;-)

If you could explain your problem in more detail I am sure we can find you the solution, but do not come with a negative frame of mind expecting no answer to what you think is a difficult problem ;-)
0
 
elmoredanielAuthor Commented:
Your incorrect about my expectations and my frame of mind. You seem to have superimposed some bad character onto my posts.

I won't respond to anymore replies. If this thread shouldn't be here, get a moderator to delete it.
0
 
Tacobell777Commented:
If I was wrong then I apologize for my assumption, and let us continue and try to find you the answer you were looking for.

Let us know exactly why your doing what you are wanting to do so we can understand and try to help.
0
 
elmoredanielAuthor Commented:
Using the duplicate function (which is the only function that will deep copy complex data types) on a object leds you to believe it returns a deep copy of the object, however it doesn't and this confuses many CFer's as it did me. In fact Blackstone is now going to make the function return an error so there is not confusion about the fact that you can't use that function on objects. This appears to be common knowledge on lists like cftalk and I assumed it would be here too, so I didn't feel like I should go into detail. What I am trying to do is just see if any has written a custom tag/ufd/cfc to emulate this process. It's no easy task and I wanted to shout out to every list and forum I use to see if it's been done.

I apologize for the confusion.
0
 
Tacobell777Commented:
how about a funtion that returns this ?

begin function .....
<cfreturn this />
end function
0
 
Tacobell777Commented:
but you are after a duplicate not a reference - ok, I would say that its not possible to return a duplicate.. But you already knew that.. :-(
0
 
Tacobell777Commented:
I guess the only thing you could do is intialize another object and copy the instance variables over.. You could not really create a general CFC to handle this as it depends on what structure your CFC is, i.e. where ever you store the variables.

In my case I always store them in
this.data = structNew(), so I could write a CFC that copies this over..
0
 
elmoredanielAuthor Commented:
Hey, I wouldn't say that you can't create such a cfc. MX has given us tools to access this information. Such as the GetMetaData() function and I'm sure getPageContext() would play a key role. I just wish someone had the time and experience to put it all together, man I'd be willing to pay for such a component.
0
 
Tacobell777Commented:
ok, I guess you could look at the properties in the meta data, but that would only tell you which ones are expected, not where you store them in the CFC. Thats why I said you would need to adhere to some kind of structure.
0
 
elmoredanielAuthor Commented:
Well the stucture is the "this" scope itself. You would want everything in that scope copied anyway, there isn't a need for this.data.
0
 
Tacobell777Commented:
no because you would not want to copy everything in the this scope.

You would want to instantiate a new object, then ONLY copy the instance variables over from the CFC in the application scope.
You already know you cannot duplicate a CFC, and all you want is a duplicate CFC with the same variables set as the one in the application scope, right?

Doing this would be the same as having duplicate working on a CFC, or am I missing something here?
0
 
elmoredanielAuthor Commented:
Possibly, I'm not sure if I entirely follow what angle your viewing the problem from, perhaps our text based communication is breaking down. Someone in my ColdFusion User Group (i'm in the Dallas/Fort Worth area) just sent me this code. I haven't analyzied it yet, but from my tests, it appears to create a perfect copy!  :)

<cfcomponent>
      <cfset this.iterations = 0>
      <cfset this.maxIterations = 23>
 
<cffunction name="init" access="public" returntype="any" output="false">

</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></cfoutput>
                        <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','cfcDuplicator');
          duplicator.init();
            </cfscript>
              <cfset "newStruct.#item#" = duplicator.clone(Evaluate("myStruct.#item#"))>
    </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>
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 13
  • 11
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now