在 ColdFusion 8 之前的版本中,如果结构中有任何组件,则重复函数会引发错误。在 8 及更高版本中它可以工作,但是在复制组件时会出现问题。
所以,我需要的是一种创建忽略组件的结构的深层副本的方法。出于我的调试目的,我需要代码中特定点的变量范围的快照,因此效率并不重要,因为它永远不会脱离开发环境。目前使用 CF 7,如果只是为了解决这个直接的问题,我会接受 8 的报价,但我不控制升级:(
在 ColdFusion 8 之前的版本中,如果结构中有任何组件,则重复函数会引发错误。在 8 及更高版本中它可以工作,但是在复制组件时会出现问题。
所以,我需要的是一种创建忽略组件的结构的深层副本的方法。出于我的调试目的,我需要代码中特定点的变量范围的快照,因此效率并不重要,因为它永远不会脱离开发环境。目前使用 CF 7,如果只是为了解决这个直接的问题,我会接受 8 的报价,但我不控制升级:(
当你正在杀死脑细胞时,我尝试了一个递归函数;)它不包括组件和 java/com 对象。哪个 MX7 都不能复制。我将函数放入组件中以避免篡改variables
范围。然后将实例存储在request
作用域中。
它没有经过严格的测试。所以我确信还有改进的余地。
用法
<cfset request.util = createObject("component", "Util")>
<cfset request.copy = request.util.duplicateStructMinusObjects(variables)>
<cfdump var="#request.copy#">
实用程序.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>
无论您思考/搜索多长时间,您总是在提出问题后立即给出答案。
我可以通过故意误用 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>
这确实会进行深层复制,但如果组件低于对象的第一级,这仍然是一个问题。我想创建一个递归方法,但是星期五的下班时间过去了一个半小时。相反,我会在酒吧杀死脑细胞,如果我不忘记的话,可能会在星期一用递归方法更新它。