如何深入复制(克隆)结构而忽略组件

时间:2011-09-16 21:53:03

标签: coldfusion coldfusion-7 coldfusion-6

在8之前的ColdFusion版本中,如果结构中有任何组件,则复制函数会抛出错误。在8及以后它可以工作,但复制组件时会出现问题。

所以,我需要的是一种创建忽略组件的结构的深层副本的方法。出于我的目的,它是用于调试的,我需要在代码中的特定点处获得变量范围的快照,因此效率并不重要,因为这将永远不会使其脱离开发环境。目前使用CF 7,如果只是解决这个问题,我会采取8个优惠,但我不控制升级:(

2 个答案:

答案 0 :(得分:5)

当你开始杀死脑细胞时,我对一个递归函数进行了尝试;)它排除了组件和java / com对象。 MX7都不能复制。我将函数放入组件中以避免篡改variables范围。然后将实例存储在request范围内。

未经过严格测试。所以我相信还有改进的余地。

<强>用法

<cfset request.util = createObject("component", "Util")>
<cfset request.copy = request.util.duplicateStructMinusObjects(variables)>
<cfdump var="#request.copy#">

<强> Util.cfc

<cfcomponent>
    <cfscript>
            function duplicateArrayMinusObjects(input) {
                    var x      = "";
                    var value  = "";
                    var output = arrayNew(1);

                    for (x = 1; x lte arrayLen(arguments.input); x = x + 1) {
                            value = arguments.input[x];

                            // note components are considered structures
                            if (IsStruct(value) and not IsObject(value)) {
                                    arrayAppend(output, duplicateStructMinusObjects(value));
                            }
                            else if (IsArray(value)) {
                                    arrayAppend(output, duplicateArrayMinusObjects(value));                
                            }
                            else if (not IsObject(value)){        
                                    arrayAppend(output, duplicate(value));
                            }
                    }        
                    return output;
            }

            function duplicateStructMinusObjects(input) {
                    var key    = "";
                    var value  = "";
                    var output = structNew();

                    for (key in arguments.input) {
                            value = arguments.input[key];

                            // note components are considered structures
                            if (IsStruct(value) and not IsObject(value)) {
                                    output[key] = duplicateStructMinusObjects(value);
                            }
                            else if (IsArray(value)) {
                                    output[key] = duplicateArrayMinusObjects(value);
                            }
                            else if (not IsObject(value)){        
                                    output[key] = duplicate(value);
                            }
                    }

                    return output;
            }
    </cfscript>
</cfcomponent> 

答案 1 :(得分:1)

无论你多久思考/搜索,你总是在提出问题后想出答案。

我能够通过故意误用try / catch来解决这个问题,所以我循环遍历结构,尝试从每个项目中创建一个对象,就像它是一个组件一样,并且出错,复制它到我的快照结构。我还必须将它存储在不同的范围内,在我的情况下,我使用了session,因为如果我让它转到默认变量,就会有一个循环引用,导致一个具有无限数量子节点的结构。

编辑:这不是我想到的,不管怎样,见下文

<cfset session.varSnapShot = StructNew()>
<cfset loopList = StructKeyList(variables)>
<cfloop from="1" to="#ListLen(loopList)#" index="i">
    <cftry>
        <cfobject name="x#i#" component="#variables[ListGetAt(loopList,i)]#">
        <cfcatch>
            <cfset session.varSnapShot[ListGetAt(loopList,i)]= variables[ListGetAt(loopList,i)]>
        </cfcatch>
    </cftry>
</cfloop>

编辑:由于以上实际上并没有做深刻的复制(感谢Leigh),我想出了这个:

<cfloop from="1" to="#ListLen(loopList)#" index="i">
    <cfset metaData = GetMetaData(variables[ListGetAt(loopList,i)])>
    <cfif isStruct(metaData) AND isDefined("metaData.type") AND metaData.type EQ "component">
    <cfelse>
        <cfset session.varSnapShot[ListGetAt(loopList,i)]= duplicate(variables[ListGetAt(loopList,i)])>
    </cfif>
</cfloop>

这会产生深层复制,但如果组件低于对象的第一级,则仍然会出现问题。我想创建一个递归方法,但是星期五的退出时间是一个半小时。我会在酒吧杀死脑细胞,如果我不忘记的话,也可以在星期一用递归方法更新它。

相关问题